issues.rb 5.8 KB
Newer Older
1
module API
N
Nihad Abbasov 已提交
2 3 4 5
  # Issues API
  class Issues < Grape::API
    before { authenticate! }

J
jubianchi 已提交
6 7 8
    helpers do
      def filter_issues_state(issues, state = nil)
        case state
9 10
        when 'opened' then issues.opened
        when 'closed' then issues.closed
11
        else issues
J
jubianchi 已提交
12 13
        end
      end
J
jubianchi 已提交
14 15 16 17

      def filter_issues_labels(issues, labels)
        issues.includes(:labels).where("labels.title" => labels.split(','))
      end
J
jubianchi 已提交
18 19
    end

N
Nihad Abbasov 已提交
20 21 22
    resource :issues do
      # Get currently authenticated user's issues
      #
J
jubianchi 已提交
23 24
      # Parameters:
      #   state (optional) - Return "opened" or "closed" issues
J
jubianchi 已提交
25 26
      #   labels (optional) - Comma-separated list of label names

J
jubianchi 已提交
27
      # Example Requests:
N
Nihad Abbasov 已提交
28
      #   GET /issues
J
jubianchi 已提交
29 30
      #   GET /issues?state=opened
      #   GET /issues?state=closed
J
jubianchi 已提交
31 32 33
      #   GET /issues?labels=foo
      #   GET /issues?labels=foo,bar
      #   GET /issues?labels=foo,bar&state=opened
N
Nihad Abbasov 已提交
34
      get do
J
jubianchi 已提交
35 36 37
        issues = current_user.issues
        issues = filter_issues_state(issues, params[:state]) unless params[:state].nil?
        issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil?
38
        issues = issues.order('issues.id DESC')
J
jubianchi 已提交
39 40

        present paginate(issues), with: Entities::Issue
N
Nihad Abbasov 已提交
41 42 43 44 45 46 47
      end
    end

    resource :projects do
      # Get a list of project issues
      #
      # Parameters:
48
      #   id (required) - The ID of a project
J
jubianchi 已提交
49
      #   state (optional) - Return "opened" or "closed" issues
J
jubianchi 已提交
50
      #   labels (optional) - Comma-separated list of label names
J
jubianchi 已提交
51 52
      #
      # Example Requests:
N
Nihad Abbasov 已提交
53
      #   GET /projects/:id/issues
J
jubianchi 已提交
54 55
      #   GET /projects/:id/issues?state=opened
      #   GET /projects/:id/issues?state=closed
J
jubianchi 已提交
56 57 58 59
      #   GET /projects/:id/issues
      #   GET /projects/:id/issues?labels=foo
      #   GET /projects/:id/issues?labels=foo,bar
      #   GET /projects/:id/issues?labels=foo,bar&state=opened
N
Nihad Abbasov 已提交
60
      get ":id/issues" do
J
jubianchi 已提交
61 62 63
        issues = user_project.issues
        issues = filter_issues_state(issues, params[:state]) unless params[:state].nil?
        issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil?
64
        issues = issues.order('issues.id DESC')
J
jubianchi 已提交
65 66

        present paginate(issues), with: Entities::Issue
N
Nihad Abbasov 已提交
67 68 69 70 71
      end

      # Get a single project issue
      #
      # Parameters:
72
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
73 74 75 76 77
      #   issue_id (required) - The ID of a project issue
      # Example Request:
      #   GET /projects/:id/issues/:issue_id
      get ":id/issues/:issue_id" do
        @issue = user_project.issues.find(params[:issue_id])
78
        present @issue, with: Entities::Issue
N
Nihad Abbasov 已提交
79 80 81 82 83
      end

      # Create a new project issue
      #
      # Parameters:
84
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
85 86 87 88 89 90 91 92
      #   title (required) - The title of an issue
      #   description (optional) - The description of an issue
      #   assignee_id (optional) - The ID of a user to assign issue
      #   milestone_id (optional) - The ID of a milestone to assign issue
      #   labels (optional) - The labels of an issue
      # Example Request:
      #   POST /projects/:id/issues
      post ":id/issues" do
93 94
        required_attributes! [:title]
        attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id]
95

96
        # Validate label names in advance
97 98
        if (errors = validate_label_params(params)).any?
          render_api_error!({ labels: errors }, 400)
99 100
        end

101 102 103
        issue = ::Issues::CreateService.new(user_project, current_user, attrs).execute

        if issue.valid?
104 105
          # Find or create labels and attach to issue. Labels are valid because
          # we already checked its name, so there can't be an error here
106
          if params[:labels].present?
107
            issue.add_labels_by_names(params[:labels].split(','))
108 109
          end

110 111
          present issue, with: Entities::Issue
        else
J
jubianchi 已提交
112
          render_validation_error!(issue)
N
Nihad Abbasov 已提交
113 114 115 116 117 118
        end
      end

      # Update an existing issue
      #
      # Parameters:
119
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
120 121 122 123 124 125
      #   issue_id (required) - The ID of a project issue
      #   title (optional) - The title of an issue
      #   description (optional) - The description of an issue
      #   assignee_id (optional) - The ID of a user to assign issue
      #   milestone_id (optional) - The ID of a milestone to assign issue
      #   labels (optional) - The labels of an issue
126
      #   state_event (optional) - The state event of an issue (close|reopen)
N
Nihad Abbasov 已提交
127 128 129
      # Example Request:
      #   PUT /projects/:id/issues/:issue_id
      put ":id/issues/:issue_id" do
130 131 132 133
        issue = user_project.issues.find(params[:issue_id])
        authorize! :modify_issue, issue
        attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event]

134
        # Validate label names in advance
135 136
        if (errors = validate_label_params(params)).any?
          render_api_error!({ labels: errors }, 400)
137 138
        end

139
        issue = ::Issues::UpdateService.new(user_project, current_user, attrs).execute(issue)
140

141
        if issue.valid?
142 143
          # Find or create labels and attach to issue. Labels are valid because
          # we already checked its name, so there can't be an error here
144 145
          unless params[:labels].nil?
            issue.remove_labels
146 147
            # Create and add labels to the new created issue
            issue.add_labels_by_names(params[:labels].split(','))
148 149
          end

150 151
          present issue, with: Entities::Issue
        else
J
jubianchi 已提交
152
          render_validation_error!(issue)
N
Nihad Abbasov 已提交
153 154 155
        end
      end

156
      # Delete a project issue (deprecated)
N
Nihad Abbasov 已提交
157 158
      #
      # Parameters:
159
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
160 161 162 163
      #   issue_id (required) - The ID of a project issue
      # Example Request:
      #   DELETE /projects/:id/issues/:issue_id
      delete ":id/issues/:issue_id" do
164
        not_allowed!
N
Nihad Abbasov 已提交
165 166 167 168
      end
    end
  end
end