summaryrefslogtreecommitdiff
path: root/lib/api/milestones.rb
blob: e7ab82f08dbc5a7c30a2d74ec6b1796af41b9019 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
module API
  class Milestones < Grape::API
    include PaginationParams

    before { authenticate! }

    helpers do
      def filter_milestones_state(milestones, state)
        case state
        when 'active' then milestones.active
        when 'closed' then milestones.closed
        else milestones
        end
      end

      params :optional_params do
        optional :description, type: String, desc: 'The description of the milestone'
        optional :due_date, type: String, desc: 'The due date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
        optional :start_date, type: String, desc: 'The start date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
      end
    end

    params do
      requires :id, type: String, desc: 'The ID of a project'
    end
    resource :projects, requirements: { id: %r{[^/]+} } do
      desc 'Get a list of project milestones' do
        success Entities::Milestone
      end
      params do
        optional :state, type: String, values: %w[active closed all], default: 'all',
                         desc: 'Return "active", "closed", or "all" milestones'
        optional :iids, type: Array[Integer], desc: 'The IIDs of the milestones'
        optional :search, type: String, desc: 'The search criteria for the title or description of the milestone'
        use :pagination
      end
      get ":id/milestones" do
        authorize! :read_milestone, user_project

        milestones = user_project.milestones
        milestones = filter_milestones_state(milestones, params[:state])
        milestones = filter_by_iid(milestones, params[:iids]) if params[:iids].present?
        milestones = filter_by_search(milestones, params[:search]) if params[:search]

        present paginate(milestones), with: Entities::Milestone
      end

      desc 'Get a single project milestone' do
        success Entities::Milestone
      end
      params do
        requires :milestone_id, type: Integer, desc: 'The ID of a project milestone'
      end
      get ":id/milestones/:milestone_id" do
        authorize! :read_milestone, user_project

        milestone = user_project.milestones.find(params[:milestone_id])
        present milestone, with: Entities::Milestone
      end

      desc 'Create a new project milestone' do
        success Entities::Milestone
      end
      params do
        requires :title, type: String, desc: 'The title of the milestone'
        use :optional_params
      end
      post ":id/milestones" do
        authorize! :admin_milestone, user_project

        milestone = ::Milestones::CreateService.new(user_project, current_user, declared_params).execute

        if milestone.valid?
          present milestone, with: Entities::Milestone
        else
          render_api_error!("Failed to create milestone #{milestone.errors.messages}", 400)
        end
      end

      desc 'Update an existing project milestone' do
        success Entities::Milestone
      end
      params do
        requires :milestone_id, type: Integer, desc: 'The ID of a project milestone'
        optional :title, type: String, desc: 'The title of the milestone'
        optional :state_event, type: String, values: %w[close activate],
                               desc: 'The state event of the milestone '
        use :optional_params
        at_least_one_of :title, :description, :due_date, :state_event
      end
      put ":id/milestones/:milestone_id" do
        authorize! :admin_milestone, user_project
        milestone = user_project.milestones.find(params.delete(:milestone_id))

        milestone_params = declared_params(include_missing: false)
        milestone = ::Milestones::UpdateService.new(user_project, current_user, milestone_params).execute(milestone)

        if milestone.valid?
          present milestone, with: Entities::Milestone
        else
          render_api_error!("Failed to update milestone #{milestone.errors.messages}", 400)
        end
      end

      desc 'Get all issues for a single project milestone' do
        success Entities::IssueBasic
      end
      params do
        requires :milestone_id, type: Integer, desc: 'The ID of a project milestone'
        use :pagination
      end
      get ":id/milestones/:milestone_id/issues" do
        authorize! :read_milestone, user_project

        milestone = user_project.milestones.find(params[:milestone_id])

        finder_params = {
          project_id: user_project.id,
          milestone_title: milestone.title,
          sort: 'position_asc'
        }

        issues = IssuesFinder.new(current_user, finder_params).execute
        present paginate(issues), with: Entities::IssueBasic, current_user: current_user, project: user_project
      end

      desc 'Get all merge requests for a single project milestone' do
        detail 'This feature was introduced in GitLab 9.'
        success Entities::MergeRequestBasic
      end
      params do
        requires :milestone_id, type: Integer, desc: 'The ID of a project milestone'
        use :pagination
      end
      get ':id/milestones/:milestone_id/merge_requests' do
        authorize! :read_milestone, user_project

        milestone = user_project.milestones.find(params[:milestone_id])

        finder_params = {
          project_id: user_project.id,
          milestone_id: milestone.id,
          sort: 'position_asc'
        }

        merge_requests = MergeRequestsFinder.new(current_user, finder_params).execute
        present paginate(merge_requests),
          with: Entities::MergeRequestBasic,
          current_user: current_user,
          project: user_project
      end
    end
  end
end