plan_my_stuff 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/CONFIGURATION.md +53 -1
- data/README.md +2 -30
- data/app/controllers/plan_my_stuff/comments_controller.rb +21 -10
- data/app/controllers/plan_my_stuff/issues/approvals_controller.rb +13 -4
- data/app/controllers/plan_my_stuff/issues/closures_controller.rb +12 -6
- data/app/controllers/plan_my_stuff/issues/links_controller.rb +14 -8
- data/app/controllers/plan_my_stuff/issues/takes_controller.rb +19 -17
- data/app/controllers/plan_my_stuff/issues/viewers_controller.rb +15 -9
- data/app/controllers/plan_my_stuff/issues/waitings_controller.rb +14 -8
- data/app/controllers/plan_my_stuff/issues_controller.rb +19 -5
- data/app/controllers/plan_my_stuff/labels_controller.rb +14 -8
- data/app/controllers/plan_my_stuff/project_items/assignments_controller.rb +6 -0
- data/app/controllers/plan_my_stuff/project_items/statuses_controller.rb +3 -0
- data/app/controllers/plan_my_stuff/project_items_controller.rb +11 -4
- data/app/controllers/plan_my_stuff/projects_controller.rb +14 -0
- data/app/controllers/plan_my_stuff/testing_project_items/results_controller.rb +3 -0
- data/app/controllers/plan_my_stuff/testing_project_items_controller.rb +5 -0
- data/app/controllers/plan_my_stuff/testing_projects_controller.rb +12 -0
- data/app/views/plan_my_stuff/issues/index.html.erb +1 -1
- data/app/views/plan_my_stuff/issues/partials/_approvals.html.erb +5 -5
- data/app/views/plan_my_stuff/issues/partials/_form.html.erb +1 -1
- data/app/views/plan_my_stuff/issues/partials/_links.html.erb +3 -3
- data/app/views/plan_my_stuff/issues/partials/_viewers.html.erb +2 -2
- data/app/views/plan_my_stuff/issues/show.html.erb +8 -8
- data/app/views/plan_my_stuff/projects/show.html.erb +3 -1
- data/app/views/plan_my_stuff/testing_projects/partials/_item.html.erb +1 -1
- data/lib/generators/plan_my_stuff/install/templates/initializer.rb +6 -0
- data/lib/plan_my_stuff/configuration.rb +61 -5
- data/lib/plan_my_stuff/issue.rb +91 -15
- data/lib/plan_my_stuff/repo.rb +28 -0
- data/lib/plan_my_stuff/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 15988155f3d1798b5b0f43cbb1597f7e8b7ed881feb3db2504da7ecd74ab9c59
|
|
4
|
+
data.tar.gz: 35f298dce675a86ca15153a354411c23806e8420374fe5eb4fd7d2c392e0ed9d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 838ebf5cb77a3467fb291d76acd9b2ded4cc40d88e65673ca41374324736c6cdc11e5bbc0ed7e04eaf0c0bb5ac4f799c3052379cdc87edcd7343dc30be370059
|
|
7
|
+
data.tar.gz: b30d829c2255b61485c72d639992f1095f9726b7e6d8952114eef2e44c91f1016c0f05bd3abd238faf0be83a37c8b75ef492208351d33cbbe1f2f689270e7614
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Every controller action now yields its primary object to a block when subclassed, so consumers can do
|
|
8
|
+
`super do |obj| ... end` to wedge in audit-log / instrumentation without rewriting the action. Webhook
|
|
9
|
+
controllers yield `(payload, result)`. See [CONFIGURATION.md](CONFIGURATION.md).
|
|
10
|
+
|
|
11
|
+
## 0.18.0
|
|
12
|
+
|
|
13
|
+
### Breaking
|
|
14
|
+
|
|
15
|
+
- `PMS::Issue#to_param` now returns `"Nickname-number"` (e.g. `"Rawr-1234"`) instead of the default ActiveModel id.
|
|
16
|
+
Single-issue URLs change from `/issues/1234?repo=rawr` to `/issues/Rawr-1234`. Consuming apps using
|
|
17
|
+
`youtrack_issue_path(@issue)` work natively; any hand-rolled URLs that passed `@issue.number` plus a `repo:`
|
|
18
|
+
query param must switch to `@issue` (or `@issue.to_param`). The mounted engine's controllers and views have
|
|
19
|
+
been updated to the new shape, as has the markdown link embedded in the GitHub issue body via
|
|
20
|
+
`Issue#user_link`.
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- `config.repo_nicknames` (default `{}`) -- Symbol-keyed map from repo key to the human-readable label used as
|
|
25
|
+
the `Issue#to_param` prefix. Missing keys fall back to `key.to_s.titleize`, so `:rawr` -> `"Rawr"` is free;
|
|
26
|
+
only divergent ones (e.g. `safety: 'Compliance'`) need an entry.
|
|
27
|
+
- `Configuration#repo_nickname_for(key)` accessor, `Repo#nickname`, and `Repo.from_nickname!` for the inverse
|
|
28
|
+
lookup used by `Issue.from_param`.
|
|
29
|
+
- `Issue#to_param` and `Issue.from_param` -- the latter parses `"Nickname-1234"` back into `[Repo, Integer]`.
|
|
30
|
+
- `Issue.find` first arg now accepts a nickname-id String (e.g. `"Rawr-1234"`) in addition to Integer / digit-
|
|
31
|
+
String + `repo:` kwarg. The nickname form ignores `repo:`.
|
|
32
|
+
|
|
3
33
|
## 0.17.0
|
|
4
34
|
|
|
5
35
|
### Added
|
data/CONFIGURATION.md
CHANGED
|
@@ -37,13 +37,17 @@ config.organization = 'YourOrg'
|
|
|
37
37
|
|---|---|---|---|
|
|
38
38
|
| `repos` | `Hash{Symbol => String}` | `{}` | Named repo configs mapping a key to an `Org/Repo` string. |
|
|
39
39
|
| `default_repo` | `Symbol, nil` | `nil` | Repo key used when callers omit the `repo:` param. |
|
|
40
|
+
| `repo_nicknames` | `Hash{Symbol => String}` | `{}` | `Issue#to_param` prefix override (default `key.titleize`). |
|
|
40
41
|
|
|
41
42
|
```ruby
|
|
42
43
|
config.repos = { element: 'YourOrg/Element', underwriter: 'YourOrg/Underwriter' }
|
|
43
44
|
config.default_repo = :element
|
|
45
|
+
config.repo_nicknames = { safety: 'Compliance' } # :element -> "Element", :underwriter -> "Underwriter" come free
|
|
44
46
|
```
|
|
45
47
|
|
|
46
|
-
`repos` can be mutated via `config.repos[:key] = '...'` or set via `config.repos = { key: 'MyOrg/MyRepo' }
|
|
48
|
+
`repos` can be mutated via `config.repos[:key] = '...'` or set via `config.repos = { key: 'MyOrg/MyRepo' }`.
|
|
49
|
+
`Issue#to_param` then returns `"Element-1234"` / `"Compliance-567"`, encoding both repo and number in a single
|
|
50
|
+
URL segment so `youtrack_issue_path(@issue)` works without a `repo:` query param.
|
|
47
51
|
|
|
48
52
|
## Projects
|
|
49
53
|
|
|
@@ -370,6 +374,54 @@ Controllable keys (with gem defaults):
|
|
|
370
374
|
| `:'webhooks/github'` | `plan_my_stuff/webhooks/github` |
|
|
371
375
|
| `:'webhooks/aws'` | `plan_my_stuff/webhooks/aws` |
|
|
372
376
|
|
|
377
|
+
### Customizing per-action behavior
|
|
378
|
+
|
|
379
|
+
Every mounted route resolves its controller through `config.controller_for(key)`. Subclass a gem controller in your
|
|
380
|
+
own app and register it to wedge in `before_action`s, authentication, or response tweaks - no monkey patching:
|
|
381
|
+
|
|
382
|
+
```ruby
|
|
383
|
+
# app/controllers/my_app/issues_controller.rb
|
|
384
|
+
class MyApp::IssuesController < PMS::IssuesController
|
|
385
|
+
before_action :authenticate_user!
|
|
386
|
+
before_action :authorize_ticket_access
|
|
387
|
+
end
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
```ruby
|
|
391
|
+
# config/initializers/plan_my_stuff.rb
|
|
392
|
+
PlanMyStuff.configure do |config|
|
|
393
|
+
config.controllers[:issues] = 'my_app/issues'
|
|
394
|
+
end
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
For per-action side effects (audit log, metrics, notifications) without rewriting the action, yielding actions
|
|
398
|
+
pass their primary object to an optional block on the happy path. Call `super do |obj| ... end` from a subclass:
|
|
399
|
+
|
|
400
|
+
```ruby
|
|
401
|
+
class MyApp::IssuesController < PMS::IssuesController
|
|
402
|
+
def create
|
|
403
|
+
super do |issue|
|
|
404
|
+
AuditLog.record(actor: current_user, action: :issue_created, target: issue)
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def update
|
|
409
|
+
super do |issue|
|
|
410
|
+
AuditLog.record(actor: current_user, action: :issue_updated, target: issue)
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Contract:
|
|
417
|
+
|
|
418
|
+
- The yield fires on the happy path, after the model load / write succeeds and before the gem's default
|
|
419
|
+
`flash[:success]` + `redirect_to`. Error branches, `not_found`, and authorization redirects do not yield.
|
|
420
|
+
- Read actions (`index`, `show`, `new`, `edit`) yield before the implicit render; `index` yields the collection,
|
|
421
|
+
the rest yield the single object.
|
|
422
|
+
- If your block calls `render` or `redirect_to`, the gem's default response is skipped (the action checks
|
|
423
|
+
`performed?`), so you can fully replace the response from the block.
|
|
424
|
+
|
|
373
425
|
### Parent controller
|
|
374
426
|
|
|
375
427
|
| Option | Type | Default | Description |
|
data/README.md
CHANGED
|
@@ -787,34 +787,6 @@ All routes are under the engine's mount point. Each group can be disabled via `c
|
|
|
787
787
|
|
|
788
788
|
## Controller overrides
|
|
789
789
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
```ruby
|
|
793
|
-
# app/controllers/my_app/issues_controller.rb
|
|
794
|
-
class MyApp::IssuesController < PMS::IssuesController
|
|
795
|
-
before_action :authenticate_user!
|
|
796
|
-
before_action :authorize_ticket_access
|
|
797
|
-
end
|
|
798
|
-
```
|
|
799
|
-
|
|
800
|
-
```ruby
|
|
801
|
-
# config/initializers/plan_my_stuff.rb
|
|
802
|
-
PlanMyStuff.configure do |config|
|
|
803
|
-
config.controllers['issues'] = 'my_app/issues'
|
|
804
|
-
end
|
|
805
|
-
```
|
|
806
|
-
|
|
807
|
-
Overridable keys (see `PMS::Configuration::DEFAULT_CONTROLLERS`):
|
|
808
|
-
|
|
809
|
-
```text
|
|
810
|
-
issues issues/closures
|
|
811
|
-
comments issues/viewers
|
|
812
|
-
labels issues/takes
|
|
813
|
-
projects issues/waitings
|
|
814
|
-
project_items issues/links
|
|
815
|
-
testing_projects issues/approvals
|
|
816
|
-
testing_project_items project_items/statuses
|
|
817
|
-
webhooks/github project_items/assignments
|
|
818
|
-
webhooks/aws testing_project_items/results
|
|
819
|
-
```
|
|
790
|
+
See [CONFIGURATION.md](CONFIGURATION.md#controller-overrides) for the full walkthrough including subclassing,
|
|
791
|
+
per-route registration, and the per-action block hook.
|
|
820
792
|
|
|
@@ -4,9 +4,9 @@ module PlanMyStuff
|
|
|
4
4
|
class CommentsController < PlanMyStuff::ApplicationController
|
|
5
5
|
# POST /issues/:issue_id/comments
|
|
6
6
|
def create
|
|
7
|
-
@issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
7
|
+
@issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
8
8
|
|
|
9
|
-
PlanMyStuff::Comment.create!(
|
|
9
|
+
comment = PlanMyStuff::Comment.create!(
|
|
10
10
|
issue: @issue,
|
|
11
11
|
body: comment_params[:body],
|
|
12
12
|
user: pms_current_user,
|
|
@@ -14,12 +14,15 @@ module PlanMyStuff
|
|
|
14
14
|
waiting_on_reply: comment_params[:waiting_on_reply] == '1',
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
+
yield(comment) if block_given?
|
|
18
|
+
return if performed?
|
|
19
|
+
|
|
17
20
|
flash[:success] = 'Comment was successfully created.'
|
|
18
|
-
redirect_to(plan_my_stuff.issue_path(@issue
|
|
21
|
+
redirect_to(plan_my_stuff.issue_path(@issue))
|
|
19
22
|
rescue PlanMyStuff::LockedIssueError => e
|
|
20
23
|
pms_handle_rescue(e)
|
|
21
24
|
flash[:error] = 'This issue is locked; no new comments can be posted.'
|
|
22
|
-
redirect_to(plan_my_stuff.issue_path(@issue
|
|
25
|
+
redirect_to(plan_my_stuff.issue_path(@issue))
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
# GET /issues/:issue_id/comments/:id/edit
|
|
@@ -27,9 +30,14 @@ module PlanMyStuff
|
|
|
27
30
|
load_comment
|
|
28
31
|
return unless @comment
|
|
29
32
|
return redirect_to_issue if issue_body_comment?
|
|
30
|
-
return if can_edit?(@comment)
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
unless can_edit?(@comment)
|
|
35
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(@issue))
|
|
36
|
+
|
|
37
|
+
return
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
yield(@comment) if block_given?
|
|
33
41
|
end
|
|
34
42
|
|
|
35
43
|
# PATCH/PUT /issues/:issue_id/comments/:id
|
|
@@ -39,7 +47,7 @@ module PlanMyStuff
|
|
|
39
47
|
return redirect_to_issue if issue_body_comment?
|
|
40
48
|
|
|
41
49
|
unless can_edit?(@comment)
|
|
42
|
-
redirect_to_unauthorized(plan_my_stuff.issue_path(@issue
|
|
50
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(@issue))
|
|
43
51
|
|
|
44
52
|
return
|
|
45
53
|
end
|
|
@@ -49,8 +57,11 @@ module PlanMyStuff
|
|
|
49
57
|
|
|
50
58
|
@comment.update!(**update_attrs, user: pms_current_user)
|
|
51
59
|
|
|
60
|
+
yield(@comment) if block_given?
|
|
61
|
+
return if performed?
|
|
62
|
+
|
|
52
63
|
flash[:success] = 'Comment was successfully updated.'
|
|
53
|
-
redirect_to(plan_my_stuff.issue_path(@issue
|
|
64
|
+
redirect_to(plan_my_stuff.issue_path(@issue))
|
|
54
65
|
rescue PlanMyStuff::StaleObjectError => e
|
|
55
66
|
pms_handle_rescue(e)
|
|
56
67
|
flash.now[:error] = 'Comment was modified by someone else. Please review the latest changes and try again.'
|
|
@@ -69,7 +80,7 @@ module PlanMyStuff
|
|
|
69
80
|
# @return [void]
|
|
70
81
|
#
|
|
71
82
|
def load_comment
|
|
72
|
-
@issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
83
|
+
@issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
73
84
|
@comment = PlanMyStuff::Comment.find(params[:id].to_i, issue: @issue)
|
|
74
85
|
end
|
|
75
86
|
|
|
@@ -96,7 +107,7 @@ module PlanMyStuff
|
|
|
96
107
|
|
|
97
108
|
# @return [void]
|
|
98
109
|
def redirect_to_issue
|
|
99
|
-
redirect_to(plan_my_stuff.issue_path(@issue
|
|
110
|
+
redirect_to(plan_my_stuff.issue_path(@issue))
|
|
100
111
|
end
|
|
101
112
|
end
|
|
102
113
|
end
|
|
@@ -23,9 +23,12 @@ module PlanMyStuff
|
|
|
23
23
|
return
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
26
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
27
27
|
issue.request_approvals!(user_ids: user_ids, user: pms_current_user)
|
|
28
28
|
|
|
29
|
+
yield(issue) if block_given?
|
|
30
|
+
return if performed?
|
|
31
|
+
|
|
29
32
|
flash[:success] = 'Approvers were successfully added.'
|
|
30
33
|
redirect_to(show_path)
|
|
31
34
|
rescue PlanMyStuff::AuthorizationError, PlanMyStuff::ValidationError => e
|
|
@@ -44,7 +47,7 @@ module PlanMyStuff
|
|
|
44
47
|
return
|
|
45
48
|
end
|
|
46
49
|
|
|
47
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
50
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
48
51
|
caller_id = pms_current_user.present? ? PlanMyStuff::UserResolver.user_id(pms_current_user) : nil
|
|
49
52
|
|
|
50
53
|
case status
|
|
@@ -71,6 +74,9 @@ module PlanMyStuff
|
|
|
71
74
|
flash[:success] = 'Response revoked.'
|
|
72
75
|
end
|
|
73
76
|
|
|
77
|
+
yield(issue) if block_given?
|
|
78
|
+
return if performed?
|
|
79
|
+
|
|
74
80
|
redirect_to(show_path)
|
|
75
81
|
rescue PlanMyStuff::AuthorizationError, PlanMyStuff::ValidationError => e
|
|
76
82
|
pms_handle_rescue(e)
|
|
@@ -85,9 +91,12 @@ module PlanMyStuff
|
|
|
85
91
|
return
|
|
86
92
|
end
|
|
87
93
|
|
|
88
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
94
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
89
95
|
issue.remove_approvers!(user_ids: [params[:id].to_i], user: pms_current_user)
|
|
90
96
|
|
|
97
|
+
yield(issue) if block_given?
|
|
98
|
+
return if performed?
|
|
99
|
+
|
|
91
100
|
flash[:success] = 'Approver was successfully removed.'
|
|
92
101
|
redirect_to(show_path)
|
|
93
102
|
rescue PlanMyStuff::AuthorizationError, PlanMyStuff::ValidationError => e
|
|
@@ -105,7 +114,7 @@ module PlanMyStuff
|
|
|
105
114
|
|
|
106
115
|
# @return [String]
|
|
107
116
|
def show_path
|
|
108
|
-
plan_my_stuff.issue_path(params[:issue_id]
|
|
117
|
+
plan_my_stuff.issue_path(params[:issue_id])
|
|
109
118
|
end
|
|
110
119
|
end
|
|
111
120
|
end
|
|
@@ -11,28 +11,34 @@ module PlanMyStuff
|
|
|
11
11
|
class ClosuresController < PlanMyStuff::ApplicationController
|
|
12
12
|
# POST /issues/:issue_id/closure
|
|
13
13
|
def create
|
|
14
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
14
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
15
15
|
issue.update!(state: :closed)
|
|
16
16
|
|
|
17
|
+
yield(issue) if block_given?
|
|
18
|
+
return if performed?
|
|
19
|
+
|
|
17
20
|
flash[:success] = 'Issue was successfully closed.'
|
|
18
|
-
redirect_to(plan_my_stuff.issue_path(issue
|
|
21
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
19
22
|
rescue PlanMyStuff::Error, ArgumentError => e
|
|
20
23
|
pms_handle_rescue(e)
|
|
21
24
|
flash[:error] = e.message
|
|
22
|
-
redirect_to(plan_my_stuff.issue_path(params[:issue_id]
|
|
25
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
# DELETE /issues/:issue_id/closure
|
|
26
29
|
def destroy
|
|
27
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
30
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
28
31
|
issue.update!(state: :open)
|
|
29
32
|
|
|
33
|
+
yield(issue) if block_given?
|
|
34
|
+
return if performed?
|
|
35
|
+
|
|
30
36
|
flash[:success] = 'Issue was successfully reopened.'
|
|
31
|
-
redirect_to(plan_my_stuff.issue_path(issue
|
|
37
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
32
38
|
rescue PlanMyStuff::Error, ArgumentError => e
|
|
33
39
|
pms_handle_rescue(e)
|
|
34
40
|
flash[:error] = e.message
|
|
35
|
-
redirect_to(plan_my_stuff.issue_path(params[:issue_id]
|
|
41
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
36
42
|
end
|
|
37
43
|
end
|
|
38
44
|
end
|
|
@@ -21,38 +21,44 @@ module PlanMyStuff
|
|
|
21
21
|
def create
|
|
22
22
|
type = link_params[:type].to_s
|
|
23
23
|
unless dispatch_allowed?(type, :add)
|
|
24
|
-
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]
|
|
24
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]))
|
|
25
25
|
return
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
28
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
29
29
|
link = add_link(issue, type)
|
|
30
30
|
|
|
31
|
+
yield(issue) if block_given?
|
|
32
|
+
return if performed?
|
|
33
|
+
|
|
31
34
|
flash[:success] = "Linked #{link}"
|
|
32
|
-
redirect_to(plan_my_stuff.issue_path(
|
|
35
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
33
36
|
rescue PlanMyStuff::ValidationError, ActiveModel::ValidationError, ArgumentError => e
|
|
34
37
|
pms_handle_rescue(e)
|
|
35
38
|
flash[:error] = e.message
|
|
36
|
-
redirect_to(plan_my_stuff.issue_path(params[:issue_id]
|
|
39
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
37
40
|
end
|
|
38
41
|
|
|
39
42
|
# DELETE /issues/:issue_id/links/:id
|
|
40
43
|
def destroy
|
|
41
44
|
type, repo, number = parse_composite_id(params[:id])
|
|
42
45
|
unless dispatch_allowed?(type, :remove)
|
|
43
|
-
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]
|
|
46
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]))
|
|
44
47
|
return
|
|
45
48
|
end
|
|
46
49
|
|
|
47
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
50
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
48
51
|
remove_link(issue, type, repo: repo, number: number)
|
|
49
52
|
|
|
53
|
+
yield(issue) if block_given?
|
|
54
|
+
return if performed?
|
|
55
|
+
|
|
50
56
|
flash[:success] = "Unlinked #{repo}##{number}"
|
|
51
|
-
redirect_to(plan_my_stuff.issue_path(
|
|
57
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
52
58
|
rescue PlanMyStuff::ValidationError, ActiveModel::ValidationError, ArgumentError => e
|
|
53
59
|
pms_handle_rescue(e)
|
|
54
60
|
flash[:error] = e.message
|
|
55
|
-
redirect_to(plan_my_stuff.issue_path(params[:issue_id]
|
|
61
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
56
62
|
end
|
|
57
63
|
|
|
58
64
|
private
|
|
@@ -11,37 +11,35 @@ module PlanMyStuff
|
|
|
11
11
|
|
|
12
12
|
# POST /issues/:issue_id/take
|
|
13
13
|
def create
|
|
14
|
-
|
|
15
|
-
repo = params[:repo]
|
|
16
|
-
|
|
17
|
-
issue = PlanMyStuff::Issue.find(issue_number, repo: repo)
|
|
14
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
18
15
|
guard_already_taken!(issue)
|
|
19
16
|
|
|
20
|
-
project_item = PlanMyStuff::Pipeline::IssueLinker.find_project_item(
|
|
17
|
+
project_item = PlanMyStuff::Pipeline::IssueLinker.find_project_item(issue.number)
|
|
21
18
|
project_item ||= add_to_pipeline(issue)
|
|
22
19
|
|
|
23
20
|
PlanMyStuff::Pipeline.take!(project_item)
|
|
24
21
|
assign_current_user(project_item)
|
|
25
|
-
flash[:success] ||= "Issue ##{issue_number} taken."
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
yield(project_item) if block_given?
|
|
24
|
+
return if performed?
|
|
25
|
+
|
|
26
|
+
flash[:success] ||= "Issue ##{issue.number} taken."
|
|
27
|
+
|
|
28
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
28
29
|
rescue ArgumentError, PlanMyStuff::Error => e
|
|
29
30
|
pms_handle_rescue(e)
|
|
30
31
|
flash[:error] = e.message
|
|
31
|
-
redirect_to(plan_my_stuff.issue_path(
|
|
32
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
# DELETE /issues/:issue_id/take
|
|
35
36
|
def destroy
|
|
36
|
-
|
|
37
|
-
repo = params[:repo]
|
|
38
|
-
|
|
39
|
-
issue = PlanMyStuff::Issue.find(issue_number, repo: repo)
|
|
37
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
40
38
|
login = current_user_login
|
|
41
39
|
guard_release!(issue, login)
|
|
42
40
|
|
|
43
41
|
remaining = issue.assignees - [login]
|
|
44
|
-
project_item = PlanMyStuff::Pipeline::IssueLinker.find_project_item(
|
|
42
|
+
project_item = PlanMyStuff::Pipeline::IssueLinker.find_project_item(issue.number)
|
|
45
43
|
|
|
46
44
|
if project_item.present?
|
|
47
45
|
if remaining.empty?
|
|
@@ -54,12 +52,16 @@ module PlanMyStuff
|
|
|
54
52
|
issue.update!(assignees: remaining)
|
|
55
53
|
end
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
yielded = project_item.presence || issue
|
|
56
|
+
yield(yielded) if block_given?
|
|
57
|
+
return if performed?
|
|
58
|
+
|
|
59
|
+
flash[:success] = "Issue ##{issue.number} released."
|
|
60
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
59
61
|
rescue ArgumentError, PlanMyStuff::Error => e
|
|
60
62
|
pms_handle_rescue(e)
|
|
61
63
|
flash[:error] = e.message
|
|
62
|
-
redirect_to(plan_my_stuff.issue_path(
|
|
64
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
private
|
|
@@ -72,7 +74,7 @@ module PlanMyStuff
|
|
|
72
74
|
return if support_user?
|
|
73
75
|
|
|
74
76
|
redirect_to_unauthorized(
|
|
75
|
-
plan_my_stuff.issue_path(params[:issue_id]
|
|
77
|
+
plan_my_stuff.issue_path(params[:issue_id]),
|
|
76
78
|
)
|
|
77
79
|
end
|
|
78
80
|
|
|
@@ -12,44 +12,50 @@ module PlanMyStuff
|
|
|
12
12
|
# POST /issues/:issue_id/viewers
|
|
13
13
|
def create
|
|
14
14
|
unless support_user?
|
|
15
|
-
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]
|
|
15
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]))
|
|
16
16
|
return
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
viewer_ids = parse_viewer_ids(params[:viewer_ids])
|
|
20
20
|
if viewer_ids.blank?
|
|
21
21
|
flash[:error] = 'No valid viewer IDs provided.'
|
|
22
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]
|
|
22
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]))
|
|
23
23
|
return
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
26
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
27
27
|
issue.add_viewers!(user_ids: viewer_ids, user: pms_current_user)
|
|
28
28
|
|
|
29
|
+
yield(issue) if block_given?
|
|
30
|
+
return if performed?
|
|
31
|
+
|
|
29
32
|
flash[:success] = 'Viewers were successfully added.'
|
|
30
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]
|
|
33
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]))
|
|
31
34
|
rescue PlanMyStuff::Error, Octokit::Error => e
|
|
32
35
|
pms_handle_rescue(e)
|
|
33
36
|
flash[:error] = e.message
|
|
34
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]
|
|
37
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]))
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
# DELETE /issues/:issue_id/viewers/:id
|
|
38
41
|
def destroy
|
|
39
42
|
unless support_user?
|
|
40
|
-
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]
|
|
43
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]))
|
|
41
44
|
return
|
|
42
45
|
end
|
|
43
46
|
|
|
44
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
47
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
45
48
|
issue.remove_viewers!(user_ids: [params[:id].to_i], user: pms_current_user)
|
|
46
49
|
|
|
50
|
+
yield(issue) if block_given?
|
|
51
|
+
return if performed?
|
|
52
|
+
|
|
47
53
|
flash[:success] = 'Viewer was successfully removed.'
|
|
48
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]
|
|
54
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]))
|
|
49
55
|
rescue PlanMyStuff::Error, Octokit::Error => e
|
|
50
56
|
pms_handle_rescue(e)
|
|
51
57
|
flash[:error] = e.message
|
|
52
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]
|
|
58
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:issue_id]))
|
|
53
59
|
end
|
|
54
60
|
end
|
|
55
61
|
end
|
|
@@ -12,37 +12,43 @@ module PlanMyStuff
|
|
|
12
12
|
# POST /issues/:issue_id/waiting
|
|
13
13
|
def create
|
|
14
14
|
unless support_user?
|
|
15
|
-
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]
|
|
15
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]))
|
|
16
16
|
return
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
19
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
20
20
|
issue.enter_waiting_on_user!(user: pms_current_user)
|
|
21
21
|
|
|
22
|
+
yield(issue) if block_given?
|
|
23
|
+
return if performed?
|
|
24
|
+
|
|
22
25
|
flash[:success] = 'Issue marked as waiting on user reply.'
|
|
23
|
-
redirect_to(plan_my_stuff.issue_path(issue
|
|
26
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
24
27
|
rescue PlanMyStuff::Error, ArgumentError => e
|
|
25
28
|
pms_handle_rescue(e)
|
|
26
29
|
flash[:error] = e.message
|
|
27
|
-
redirect_to(plan_my_stuff.issue_path(params[:issue_id]
|
|
30
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
# DELETE /issues/:issue_id/waiting
|
|
31
34
|
def destroy
|
|
32
35
|
unless support_user?
|
|
33
|
-
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]
|
|
36
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:issue_id]))
|
|
34
37
|
return
|
|
35
38
|
end
|
|
36
39
|
|
|
37
|
-
issue = PlanMyStuff::Issue.find(params[:issue_id]
|
|
40
|
+
issue = PlanMyStuff::Issue.find(params[:issue_id])
|
|
38
41
|
issue.clear_waiting_on_user!
|
|
39
42
|
|
|
43
|
+
yield(issue) if block_given?
|
|
44
|
+
return if performed?
|
|
45
|
+
|
|
40
46
|
flash[:success] = 'Waiting-on-user state cleared.'
|
|
41
|
-
redirect_to(plan_my_stuff.issue_path(issue
|
|
47
|
+
redirect_to(plan_my_stuff.issue_path(issue))
|
|
42
48
|
rescue PlanMyStuff::Error, ArgumentError => e
|
|
43
49
|
pms_handle_rescue(e)
|
|
44
50
|
flash[:error] = e.message
|
|
45
|
-
redirect_to(plan_my_stuff.issue_path(params[:issue_id]
|
|
51
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
46
52
|
end
|
|
47
53
|
end
|
|
48
54
|
end
|
|
@@ -17,11 +17,15 @@ module PlanMyStuff
|
|
|
17
17
|
page: @page,
|
|
18
18
|
per_page: @per_page,
|
|
19
19
|
)
|
|
20
|
+
|
|
21
|
+
yield(@issues) if block_given?
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
# GET /issues/new
|
|
23
25
|
def new
|
|
24
26
|
@issue = PlanMyStuff::Issue.new
|
|
27
|
+
|
|
28
|
+
yield(@issue) if block_given?
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
# POST /issues
|
|
@@ -33,8 +37,11 @@ module PlanMyStuff
|
|
|
33
37
|
user: pms_current_user,
|
|
34
38
|
)
|
|
35
39
|
|
|
40
|
+
yield(@issue) if block_given?
|
|
41
|
+
return if performed?
|
|
42
|
+
|
|
36
43
|
flash[:success] = 'Issue was successfully created.'
|
|
37
|
-
redirect_to(plan_my_stuff.issue_path(@issue
|
|
44
|
+
redirect_to(plan_my_stuff.issue_path(@issue))
|
|
38
45
|
rescue PlanMyStuff::ValidationError => e
|
|
39
46
|
pms_handle_rescue(e)
|
|
40
47
|
@issue = PlanMyStuff::Issue.new(title: issue_params[:title], body: issue_params[:body])
|
|
@@ -44,22 +51,26 @@ module PlanMyStuff
|
|
|
44
51
|
|
|
45
52
|
# GET /issues/:id
|
|
46
53
|
def show
|
|
47
|
-
@issue = PlanMyStuff::Issue.find(params[:id]
|
|
54
|
+
@issue = PlanMyStuff::Issue.find(params[:id])
|
|
48
55
|
@comments = filter_visible_comments(@issue.comments)
|
|
49
56
|
@current_user_id = pms_current_user.present? ? PlanMyStuff::UserResolver.user_id(pms_current_user) : nil
|
|
50
57
|
@current_user_login = PlanMyStuff.configuration.github_login_for[@current_user_id]
|
|
51
58
|
@pipeline_enabled = PlanMyStuff.configuration.pipeline_enabled
|
|
52
59
|
@pipeline_item = load_pipeline_item(@issue.number) if @pipeline_enabled
|
|
60
|
+
|
|
61
|
+
yield(@issue) if block_given?
|
|
53
62
|
end
|
|
54
63
|
|
|
55
64
|
# GET /issues/:id/edit
|
|
56
65
|
def edit
|
|
57
|
-
@issue = PlanMyStuff::Issue.find(params[:id]
|
|
66
|
+
@issue = PlanMyStuff::Issue.find(params[:id])
|
|
67
|
+
|
|
68
|
+
yield(@issue) if block_given?
|
|
58
69
|
end
|
|
59
70
|
|
|
60
71
|
# PATCH/PUT /issues/:id
|
|
61
72
|
def update
|
|
62
|
-
@issue = PlanMyStuff::Issue.find(params[:id]
|
|
73
|
+
@issue = PlanMyStuff::Issue.find(params[:id])
|
|
63
74
|
|
|
64
75
|
@issue.update!(
|
|
65
76
|
title: issue_params[:title],
|
|
@@ -67,8 +78,11 @@ module PlanMyStuff
|
|
|
67
78
|
labels: parse_labels(issue_params[:labels]),
|
|
68
79
|
)
|
|
69
80
|
|
|
81
|
+
yield(@issue) if block_given?
|
|
82
|
+
return if performed?
|
|
83
|
+
|
|
70
84
|
flash[:success] = 'Issue was successfully updated.'
|
|
71
|
-
redirect_to(plan_my_stuff.issue_path(@issue
|
|
85
|
+
redirect_to(plan_my_stuff.issue_path(@issue))
|
|
72
86
|
rescue PlanMyStuff::StaleObjectError => e
|
|
73
87
|
pms_handle_rescue(e)
|
|
74
88
|
flash.now[:error] = 'Issue was modified by someone else. Please review the latest changes and try again.'
|