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

time_tracking_endpoints.rb « api « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: dd8ad2cc1448f4d72429381ee514fe913a6b808a (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
155
156
157
158
159
160
# frozen_string_literal: true

module API
  module TimeTrackingEndpoints
    extend ActiveSupport::Concern

    included do
      helpers do
        def issuable_name
          declared_params.key?(:issue_iid) ? 'issue' : 'merge_request'
        end

        def issuable_key
          "#{issuable_name}_iid".to_sym
        end

        def admin_issuable_key
          "admin_#{issuable_name}".to_sym
        end

        def read_issuable_key
          "read_#{issuable_name}".to_sym
        end

        def load_issuable
          @issuable ||= case issuable_name
                        when 'issue'
                          find_project_issue(params.delete(issuable_key))
                        when 'merge_request'
                          find_project_merge_request(params.delete(issuable_key))
                        end
        end

        def update_issuable(attrs)
          custom_params = declared_params(include_missing: false)
          custom_params.merge!(attrs)

          issuable = update_service.new(project: user_project, current_user: current_user, params: custom_params).execute(load_issuable)
          if issuable.valid?
            present issuable, with: Entities::IssuableTimeStats
          else
            render_validation_error!(issuable)
          end
        end

        def update_service
          issuable_name == 'issue' ? ::Issues::UpdateService : ::MergeRequests::UpdateService
        end
      end

      issuable_name            = name.end_with?('Issues') ? 'issue' : 'merge_request'
      issuable_collection_name = issuable_name.pluralize
      issuable_key             = "#{issuable_name}_iid".to_sym

      desc "Set a time estimate for a #{issuable_name}" do
        detail " Sets an estimated time of work for this #{issuable_name}."
        success Entities::IssuableTimeStats
        failure [
          { code: 401, message: 'Unauthorized' },
          { code: 404, message: 'Not found' }
        ]
        tags [issuable_collection_name]
      end
      params do
        requires issuable_key, type: Integer, desc: "The internal ID of the #{issuable_name}."
        requires :duration, type: String, desc: 'The duration in human format.', documentation: { example: '3h30m' }
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/time_estimate" do
        authorize! admin_issuable_key, load_issuable

        status :ok
        update_issuable(time_estimate: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)))
      end

      desc "Reset the time estimate for a project #{issuable_name}" do
        detail "Resets the estimated time for this #{issuable_name} to 0 seconds."
        success Entities::IssuableTimeStats
        failure [
          { code: 401, message: 'Unauthorized' },
          { code: 404, message: 'Not found' }
        ]
        tags [issuable_collection_name]
      end
      params do
        requires issuable_key, type: Integer, desc: "The internal ID of the #{issuable_name}."
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/reset_time_estimate" do
        authorize! admin_issuable_key, load_issuable

        status :ok
        update_issuable(time_estimate: 0)
      end

      desc "Add spent time for a #{issuable_name}" do
        detail "Adds spent time for this #{issuable_name}."
        success Entities::IssuableTimeStats
        failure [
          { code: 401, message: 'Unauthorized' },
          { code: 404, message: 'Not found' }
        ]
        tags [issuable_collection_name]
      end
      params do
        requires issuable_key, type: Integer, desc: "The internal ID of the #{issuable_name}."
        requires :duration, type: String, desc: 'The duration in human format.'
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/add_spent_time" do
        authorize! admin_issuable_key, load_issuable

        update_params = {
          spend_time: {
            duration: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)),
            summary: params.delete(:summary),
            user_id: current_user.id
          }
        }
        update_params[:use_specialized_service] = true if issuable_name == 'merge_request'

        update_issuable(update_params)
      end

      desc "Reset spent time for a #{issuable_name}" do
        detail "Resets the total spent time for this #{issuable_name} to 0 seconds."
        success Entities::IssuableTimeStats
        failure [
          { code: 401, message: 'Unauthorized' },
          { code: 404, message: 'Not found' }
        ]
        tags [issuable_collection_name]
      end
      params do
        requires issuable_key, type: Integer, desc: "The internal ID of the #{issuable_name}"
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/reset_spent_time" do
        authorize! admin_issuable_key, load_issuable

        status :ok
        update_issuable(spend_time: { duration: :reset, user_id: current_user.id })
      end

      desc "Get time tracking stats" do
        detail "Get time tracking stats"
        success Entities::IssuableTimeStats
        failure [
          { code: 401, message: 'Unauthorized' },
          { code: 404, message: 'Not found' }
        ]
        tags [issuable_collection_name]
      end
      params do
        requires issuable_key, type: Integer, desc: "The internal ID of the #{issuable_name}"
      end
      get ":id/#{issuable_collection_name}/:#{issuable_key}/time_stats" do
        authorize! read_issuable_key, load_issuable

        present load_issuable, with: Entities::IssuableTimeStats
      end
    end
  end
end