plan_my_stuff 0.1.1 → 0.3.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 +27 -0
- data/app/controllers/plan_my_stuff/application_controller.rb +4 -1
- data/app/controllers/plan_my_stuff/comments_controller.rb +24 -6
- data/app/controllers/plan_my_stuff/issues_controller.rb +23 -17
- data/app/controllers/plan_my_stuff/labels_controller.rb +5 -5
- data/app/controllers/plan_my_stuff/project_items_controller.rb +6 -0
- data/app/controllers/plan_my_stuff/projects_controller.rb +54 -0
- data/app/views/plan_my_stuff/issues/index.html.erb +4 -4
- data/app/views/plan_my_stuff/issues/partials/_form.html.erb +10 -6
- data/app/views/plan_my_stuff/issues/partials/_viewers.html.erb +2 -2
- data/app/views/plan_my_stuff/issues/show.html.erb +4 -4
- data/app/views/plan_my_stuff/projects/edit.html.erb +7 -0
- data/app/views/plan_my_stuff/projects/index.html.erb +2 -0
- data/app/views/plan_my_stuff/projects/new.html.erb +7 -0
- data/app/views/plan_my_stuff/projects/partials/_form.html.erb +29 -0
- data/app/views/plan_my_stuff/projects/show.html.erb +6 -4
- data/config/routes.rb +1 -1
- data/lib/generators/plan_my_stuff/install/templates/initializer.rb +10 -1
- data/lib/plan_my_stuff/application_record.rb +37 -1
- data/lib/plan_my_stuff/base_metadata.rb +23 -15
- data/lib/plan_my_stuff/client.rb +2 -22
- data/lib/plan_my_stuff/comment.rb +22 -8
- data/lib/plan_my_stuff/comment_metadata.rb +8 -2
- data/lib/plan_my_stuff/configuration.rb +82 -1
- data/lib/plan_my_stuff/custom_fields.rb +70 -0
- data/lib/plan_my_stuff/issue.rb +23 -19
- data/lib/plan_my_stuff/issue_metadata.rb +8 -2
- data/lib/plan_my_stuff/markdown.rb +1 -1
- data/lib/plan_my_stuff/project.rb +280 -19
- data/lib/plan_my_stuff/project_item.rb +19 -11
- data/lib/plan_my_stuff/project_metadata.rb +41 -0
- data/lib/plan_my_stuff/repo.rb +107 -0
- data/lib/plan_my_stuff/test_helpers.rb +10 -2
- data/lib/plan_my_stuff/version.rb +2 -2
- data/lib/plan_my_stuff.rb +2 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9b5b0d6a9e0582853ebf435a48b49fabb8dc9bd1227bddc6f2c3467d74872c80
|
|
4
|
+
data.tar.gz: 3e1df8e562940c9c1435c2edc4b88c7b85c2c2c8309b95702f8f6d3f978bdf19
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fdc842d462d7e04c163560c475bd6519e04b4b5f57b2684be5137ed32ff0bc9e257d9f09e7ab1cda06e6106065e38e4a1c80f0fea96d812841141cc14cbed4a6
|
|
7
|
+
data.tar.gz: 9e4954b597a281e4c68e1ea9ecbe2748efbcac31062f7fd3b925b887dc0616015df27df8c0122fc4165621227f5eefa13ead1ce0583cbe9dcd377ecaf0e47e23
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Validate `config.custom_fields` on `create!`/`update!` actions
|
|
8
|
+
|
|
9
|
+
### Changes
|
|
10
|
+
|
|
11
|
+
- CodeRabbit improvements
|
|
12
|
+
|
|
13
|
+
## 0.1.2
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Issues' links were looking for the issue in the default repo with the same number
|
|
18
|
+
|
|
19
|
+
## 0.1.1
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Wrong changelog included in publish
|
|
24
|
+
|
|
25
|
+
## 0.1.0
|
|
26
|
+
|
|
27
|
+
- Initial Setup
|
|
@@ -70,7 +70,10 @@ module PlanMyStuff
|
|
|
70
70
|
def parse_viewer_ids(ids_string)
|
|
71
71
|
return [] if ids_string.blank?
|
|
72
72
|
|
|
73
|
-
ids_string.split(',').filter_map
|
|
73
|
+
ids_string.split(',').filter_map do |id|
|
|
74
|
+
token = id.strip
|
|
75
|
+
token.to_i if token.match?(/\A\d+\z/)
|
|
76
|
+
end
|
|
74
77
|
end
|
|
75
78
|
end
|
|
76
79
|
end
|
|
@@ -4,7 +4,7 @@ module PlanMyStuff
|
|
|
4
4
|
class CommentsController < ApplicationController
|
|
5
5
|
# POST /issues/:issue_id/comments
|
|
6
6
|
def create
|
|
7
|
-
@issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo]
|
|
7
|
+
@issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo])
|
|
8
8
|
|
|
9
9
|
PMS::Comment.create!(
|
|
10
10
|
issue: @issue,
|
|
@@ -14,25 +14,33 @@ module PlanMyStuff
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
flash[:success] = 'Comment was successfully created.'
|
|
17
|
-
redirect_to(plan_my_stuff.issue_path(@issue.number))
|
|
17
|
+
redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# GET /issues/:issue_id/comments/:id/edit
|
|
21
21
|
def edit
|
|
22
22
|
load_comment
|
|
23
23
|
return unless @comment
|
|
24
|
+
return redirect_to_issue if issue_body_comment?
|
|
24
25
|
|
|
25
26
|
@support_user = support_user?
|
|
26
|
-
return
|
|
27
|
+
return if can_edit?(@comment)
|
|
28
|
+
|
|
29
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
# PATCH/PUT /issues/:issue_id/comments/:id
|
|
30
33
|
def update
|
|
31
34
|
load_comment
|
|
32
35
|
return unless @comment
|
|
36
|
+
return redirect_to_issue if issue_body_comment?
|
|
33
37
|
|
|
34
38
|
@support_user = support_user?
|
|
35
|
-
|
|
39
|
+
unless can_edit?(@comment)
|
|
40
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
41
|
+
|
|
42
|
+
return
|
|
43
|
+
end
|
|
36
44
|
|
|
37
45
|
update_attrs = { body: comment_params[:body] }
|
|
38
46
|
update_attrs[:visibility] = comment_params[:visibility].to_sym if @support_user && comment_params[:visibility]
|
|
@@ -40,7 +48,7 @@ module PlanMyStuff
|
|
|
40
48
|
@comment.update!(**update_attrs)
|
|
41
49
|
|
|
42
50
|
flash[:success] = 'Comment was successfully updated.'
|
|
43
|
-
redirect_to(plan_my_stuff.issue_path(@issue.number))
|
|
51
|
+
redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
44
52
|
rescue PMS::StaleObjectError
|
|
45
53
|
flash.now[:error] = 'Comment was modified by someone else. Please review the latest changes and try again.'
|
|
46
54
|
render(:edit, status: PMS.unprocessable_status)
|
|
@@ -58,7 +66,7 @@ module PlanMyStuff
|
|
|
58
66
|
# @return [void]
|
|
59
67
|
#
|
|
60
68
|
def load_comment
|
|
61
|
-
@issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo]
|
|
69
|
+
@issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo])
|
|
62
70
|
@comment = PMS::Comment.find(params[:id].to_i, issue: @issue)
|
|
63
71
|
end
|
|
64
72
|
|
|
@@ -78,5 +86,15 @@ module PlanMyStuff
|
|
|
78
86
|
|
|
79
87
|
comment.metadata.created_by == PMS::UserResolver.user_id(user)
|
|
80
88
|
end
|
|
89
|
+
|
|
90
|
+
# @return [Boolean]
|
|
91
|
+
def issue_body_comment?
|
|
92
|
+
@comment.metadata.issue_body?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @return [void]
|
|
96
|
+
def redirect_to_issue
|
|
97
|
+
redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
98
|
+
end
|
|
81
99
|
end
|
|
82
100
|
end
|
|
@@ -8,7 +8,7 @@ module PlanMyStuff
|
|
|
8
8
|
@per_page = (params[:per_page] || 25).to_i
|
|
9
9
|
@state = (params[:state] || 'open').to_sym
|
|
10
10
|
@labels = params[:labels].present? ? Array.wrap(params[:labels]) : []
|
|
11
|
-
@repo = params[:repo]
|
|
11
|
+
@repo = params[:repo]
|
|
12
12
|
|
|
13
13
|
@issues = PMS::Issue.list(
|
|
14
14
|
repo: @repo,
|
|
@@ -35,7 +35,7 @@ module PlanMyStuff
|
|
|
35
35
|
)
|
|
36
36
|
|
|
37
37
|
flash[:success] = 'Issue was successfully created.'
|
|
38
|
-
redirect_to(plan_my_stuff.issue_path(@issue.number))
|
|
38
|
+
redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
39
39
|
rescue PMS::ValidationError => e
|
|
40
40
|
@issue = PMS::Issue.new(title: issue_params[:title], body: issue_params[:body])
|
|
41
41
|
@support_user = support_user?
|
|
@@ -45,7 +45,7 @@ module PlanMyStuff
|
|
|
45
45
|
|
|
46
46
|
# GET /issues/:id
|
|
47
47
|
def show
|
|
48
|
-
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo]
|
|
48
|
+
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo])
|
|
49
49
|
@comments = filter_visible_comments(@issue.comments)
|
|
50
50
|
@support_user = support_user?
|
|
51
51
|
@current_user_id = pms_current_user.present? ? PMS::UserResolver.user_id(pms_current_user) : nil
|
|
@@ -53,13 +53,13 @@ module PlanMyStuff
|
|
|
53
53
|
|
|
54
54
|
# GET /issues/:id/edit
|
|
55
55
|
def edit
|
|
56
|
-
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo]
|
|
56
|
+
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo])
|
|
57
57
|
@support_user = support_user?
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
# PATCH/PUT /issues/:id
|
|
61
61
|
def update
|
|
62
|
-
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo]
|
|
62
|
+
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo])
|
|
63
63
|
|
|
64
64
|
@issue.update!(
|
|
65
65
|
title: issue_params[:title],
|
|
@@ -68,7 +68,7 @@ module PlanMyStuff
|
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
flash[:success] = 'Issue was successfully updated.'
|
|
71
|
-
redirect_to(plan_my_stuff.issue_path(@issue.number))
|
|
71
|
+
redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
72
72
|
rescue PMS::StaleObjectError
|
|
73
73
|
@support_user = support_user?
|
|
74
74
|
flash.now[:error] = 'Issue was modified by someone else. Please review the latest changes and try again.'
|
|
@@ -77,48 +77,54 @@ module PlanMyStuff
|
|
|
77
77
|
|
|
78
78
|
# PATCH /issues/:id/close
|
|
79
79
|
def close
|
|
80
|
-
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo]
|
|
80
|
+
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo])
|
|
81
81
|
@issue.update!(state: :closed)
|
|
82
82
|
|
|
83
83
|
flash[:success] = 'Issue was successfully closed.'
|
|
84
|
-
redirect_to(plan_my_stuff.issue_path(@issue.number))
|
|
84
|
+
redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
# PATCH /issues/:id/reopen
|
|
88
88
|
def reopen
|
|
89
|
-
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo]
|
|
89
|
+
@issue = PMS::Issue.find(params[:id].to_i, repo: params[:repo])
|
|
90
90
|
@issue.update!(state: :open)
|
|
91
91
|
|
|
92
92
|
flash[:success] = 'Issue was successfully reopened.'
|
|
93
|
-
redirect_to(plan_my_stuff.issue_path(@issue.number))
|
|
93
|
+
redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
# POST /issues/:id/add_viewers
|
|
97
97
|
def add_viewers
|
|
98
|
-
|
|
98
|
+
unless support_user?
|
|
99
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:id], repo: params[:repo]))
|
|
100
|
+
return
|
|
101
|
+
end
|
|
99
102
|
|
|
100
103
|
viewer_ids = parse_viewer_ids(params[:viewer_ids])
|
|
101
104
|
if viewer_ids.blank?
|
|
102
105
|
flash[:error] = 'No valid viewer IDs provided.'
|
|
103
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:id]))
|
|
106
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:id], repo: params[:repo]))
|
|
104
107
|
return
|
|
105
108
|
end
|
|
106
109
|
|
|
107
|
-
PMS::Issue.add_viewers(number: params[:id].to_i, user_ids: viewer_ids, repo: params[:repo]
|
|
110
|
+
PMS::Issue.add_viewers(number: params[:id].to_i, user_ids: viewer_ids, repo: params[:repo])
|
|
108
111
|
|
|
109
112
|
flash[:success] = 'Viewers were successfully added.'
|
|
110
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:id]))
|
|
113
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:id], repo: params[:repo]))
|
|
111
114
|
end
|
|
112
115
|
|
|
113
116
|
# DELETE /issues/:id/remove_viewer
|
|
114
117
|
def remove_viewer
|
|
115
|
-
|
|
118
|
+
unless support_user?
|
|
119
|
+
redirect_to_unauthorized(plan_my_stuff.issue_path(params[:id], repo: params[:repo]))
|
|
120
|
+
return
|
|
121
|
+
end
|
|
116
122
|
|
|
117
123
|
viewer_id = params[:viewer_id].to_i
|
|
118
|
-
PMS::Issue.remove_viewers(number: params[:id].to_i, user_ids: [viewer_id], repo: params[:repo]
|
|
124
|
+
PMS::Issue.remove_viewers(number: params[:id].to_i, user_ids: [viewer_id], repo: params[:repo])
|
|
119
125
|
|
|
120
126
|
flash[:success] = 'Viewer was successfully removed.'
|
|
121
|
-
redirect_to(plan_my_stuff.edit_issue_path(params[:id]))
|
|
127
|
+
redirect_to(plan_my_stuff.edit_issue_path(params[:id], repo: params[:repo]))
|
|
122
128
|
end
|
|
123
129
|
|
|
124
130
|
private
|
|
@@ -7,24 +7,24 @@ module PlanMyStuff
|
|
|
7
7
|
labels = parse_labels(params[:label_name])
|
|
8
8
|
if labels.blank?
|
|
9
9
|
flash[:error] = 'Label name is required.'
|
|
10
|
-
redirect_to(plan_my_stuff.issue_path(params[:issue_id]))
|
|
10
|
+
redirect_to(plan_my_stuff.issue_path(params[:issue_id], repo: params[:repo]))
|
|
11
11
|
return
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo]
|
|
14
|
+
issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo])
|
|
15
15
|
PMS::Label.add(issue: issue, labels: labels)
|
|
16
16
|
|
|
17
17
|
flash[:success] = 'Label was successfully added.'
|
|
18
|
-
redirect_to(plan_my_stuff.issue_path(issue.number))
|
|
18
|
+
redirect_to(plan_my_stuff.issue_path(issue.number, repo: issue.repo.full_name))
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# DELETE /issues/:issue_id/labels/:name
|
|
22
22
|
def remove_from_issue
|
|
23
|
-
issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo]
|
|
23
|
+
issue = PMS::Issue.find(params[:issue_id].to_i, repo: params[:repo])
|
|
24
24
|
PMS::Label.remove(issue: issue, labels: [params[:name]])
|
|
25
25
|
|
|
26
26
|
flash[:success] = 'Label was successfully removed.'
|
|
27
|
-
redirect_to(plan_my_stuff.issue_path(issue.number))
|
|
27
|
+
redirect_to(plan_my_stuff.issue_path(issue.number, repo: issue.repo.full_name))
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -50,6 +50,12 @@ module PlanMyStuff
|
|
|
50
50
|
|
|
51
51
|
# PATCH /projects/:project_id/items/:id/unassign
|
|
52
52
|
def unassign
|
|
53
|
+
if params[:username].blank?
|
|
54
|
+
flash[:error] = 'Username is required to unassign.'
|
|
55
|
+
redirect_to(plan_my_stuff.project_path(params[:project_id]))
|
|
56
|
+
return
|
|
57
|
+
end
|
|
58
|
+
|
|
53
59
|
item = find_project_item
|
|
54
60
|
current_assignees = item.field_values['Assignees'] || []
|
|
55
61
|
remaining = current_assignees - [params[:username]]
|
|
@@ -7,11 +7,65 @@ module PlanMyStuff
|
|
|
7
7
|
@projects = PMS::Project.list.reject(&:closed)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
# GET /projects/new
|
|
11
|
+
def new
|
|
12
|
+
@project = PMS::Project.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# POST /projects
|
|
16
|
+
def create
|
|
17
|
+
@project = PMS::Project.create!(
|
|
18
|
+
title: project_params[:title],
|
|
19
|
+
readme: project_params[:readme] || '',
|
|
20
|
+
description: project_params[:description],
|
|
21
|
+
user: pms_current_user,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
flash[:success] = 'Project was successfully created.'
|
|
25
|
+
redirect_to(plan_my_stuff.project_path(@project.number))
|
|
26
|
+
rescue PMS::ValidationError => e
|
|
27
|
+
@project = PMS::Project.new(
|
|
28
|
+
title: project_params[:title],
|
|
29
|
+
readme: project_params[:readme],
|
|
30
|
+
)
|
|
31
|
+
flash.now[:error] = e.message
|
|
32
|
+
render(:new, status: PMS.unprocessable_status)
|
|
33
|
+
end
|
|
34
|
+
|
|
10
35
|
# GET /projects/:id
|
|
11
36
|
def show
|
|
12
37
|
@project = PMS::Project.find(params[:id].to_i)
|
|
13
38
|
@statuses = @project.statuses.pluck(:name)
|
|
14
39
|
@items_by_status = @project.items.group_by(&:status)
|
|
15
40
|
end
|
|
41
|
+
|
|
42
|
+
# GET /projects/:id/edit
|
|
43
|
+
def edit
|
|
44
|
+
@project = PMS::Project.find(params[:id].to_i)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# PATCH/PUT /projects/:id
|
|
48
|
+
def update
|
|
49
|
+
@project = PMS::Project.find(params[:id].to_i)
|
|
50
|
+
|
|
51
|
+
@project.update!(
|
|
52
|
+
title: project_params[:title],
|
|
53
|
+
readme: project_params[:readme],
|
|
54
|
+
description: project_params[:description],
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
flash[:success] = 'Project was successfully updated.'
|
|
58
|
+
redirect_to(plan_my_stuff.project_path(@project.number))
|
|
59
|
+
rescue PMS::StaleObjectError
|
|
60
|
+
flash.now[:error] = 'Project was modified by someone else. Please review the latest changes and try again.'
|
|
61
|
+
render(:edit, status: PMS.unprocessable_status)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
# @return [ActionController::Parameters]
|
|
67
|
+
def project_params
|
|
68
|
+
params.require(:project).permit(:title, :readme, :description)
|
|
69
|
+
end
|
|
16
70
|
end
|
|
17
71
|
end
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<% @issues.each do |issue| %>
|
|
15
15
|
<tr>
|
|
16
16
|
<td><%= issue.number %></td>
|
|
17
|
-
<td><%= link_to(issue.title, plan_my_stuff.issue_path(issue.number)) %></td>
|
|
17
|
+
<td><%= link_to(issue.title, plan_my_stuff.issue_path(issue.number, repo: issue.repo.full_name)) %></td>
|
|
18
18
|
<td><%= issue.state %></td>
|
|
19
19
|
<td><%= issue.labels.join(', ') %></td>
|
|
20
20
|
</tr>
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
|
|
25
25
|
<nav>
|
|
26
26
|
<% if @page > 1 %>
|
|
27
|
-
<%= link_to('Previous', plan_my_stuff.issues_path(page: @page - 1, state: @state, labels: @labels)) %>
|
|
27
|
+
<%= link_to('Previous', plan_my_stuff.issues_path(page: @page - 1, state: @state, labels: @labels, repo: @repo)) %>
|
|
28
28
|
<% end %>
|
|
29
29
|
<% if @issues.size == @per_page %>
|
|
30
|
-
<%= link_to('Next', plan_my_stuff.issues_path(page: @page + 1, state: @state, labels: @labels)) %>
|
|
30
|
+
<%= link_to('Next', plan_my_stuff.issues_path(page: @page + 1, state: @state, labels: @labels, repo: @repo)) %>
|
|
31
31
|
<% end %>
|
|
32
32
|
</nav>
|
|
33
33
|
<% else %>
|
|
34
34
|
<p>No issues found.</p>
|
|
35
35
|
<% end %>
|
|
36
36
|
<br>
|
|
37
|
-
<%= link_to "New Issue", plan_my_stuff.new_issue_path %>
|
|
37
|
+
<%= link_to "New Issue", plan_my_stuff.new_issue_path(repo: @repo) %>
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
<%
|
|
2
|
-
|
|
3
|
-
url
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
<%
|
|
2
|
+
persisted = issue.persisted?
|
|
3
|
+
url =
|
|
4
|
+
if persisted
|
|
5
|
+
plan_my_stuff.issue_path(issue.number, repo: issue.repo&.full_name)
|
|
6
|
+
else
|
|
7
|
+
plan_my_stuff.issues_path(repo: issue.repo&.full_name)
|
|
8
|
+
end
|
|
9
|
+
%>
|
|
10
|
+
<%= form_with(url: url, method: persisted ? :patch : :post, scope: :issue) do |form| %>
|
|
7
11
|
<div>
|
|
8
12
|
<%= form.label(:title, 'Title') %>
|
|
9
13
|
<%= form.text_field(:title, value: issue.title) %>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<%=
|
|
10
10
|
button_to(
|
|
11
11
|
'Remove',
|
|
12
|
-
plan_my_stuff.remove_viewer_issue_path(issue.number, viewer_id: viewer_id),
|
|
12
|
+
plan_my_stuff.remove_viewer_issue_path(issue.number, viewer_id: viewer_id, repo: issue.repo.full_name),
|
|
13
13
|
method: :delete
|
|
14
14
|
)
|
|
15
15
|
%>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<p>No viewers added.</p>
|
|
21
21
|
<% end %>
|
|
22
22
|
|
|
23
|
-
<%= form_with(url: plan_my_stuff.add_viewers_issue_path(issue.number), method: :post) do |form| %>
|
|
23
|
+
<%= form_with(url: plan_my_stuff.add_viewers_issue_path(issue.number, repo: issue.repo.full_name), method: :post) do |form| %>
|
|
24
24
|
<div>
|
|
25
25
|
<%= form.label(:viewer_ids, 'Add viewer IDs (comma-separated)') %>
|
|
26
26
|
<%= form.text_field(:viewer_ids) %>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<h1><%= @issue.title %> <small>#<%= @issue.number %></small></h1>
|
|
2
2
|
|
|
3
3
|
<p>
|
|
4
|
-
<%= link_to('Edit', plan_my_stuff.edit_issue_path(@issue.number)) %>
|
|
4
|
+
<%= link_to('Edit', plan_my_stuff.edit_issue_path(@issue.number, repo: @issue.repo.full_name)) %>
|
|
5
5
|
<% if @issue.state == 'open' %>
|
|
6
|
-
<%= button_to('Close Issue', plan_my_stuff.close_issue_path(@issue.number), method: :patch) %>
|
|
6
|
+
<%= button_to('Close Issue', plan_my_stuff.close_issue_path(@issue.number, repo: @issue.repo.full_name), method: :patch) %>
|
|
7
7
|
<% else %>
|
|
8
|
-
<%= button_to('Reopen Issue', plan_my_stuff.reopen_issue_path(@issue.number), method: :patch) %>
|
|
8
|
+
<%= button_to('Reopen Issue', plan_my_stuff.reopen_issue_path(@issue.number, repo: @issue.repo.full_name), method: :patch) %>
|
|
9
9
|
<% end %>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
<%= PlanMyStuff::Markdown.render(comment.body || '').html_safe %>
|
|
36
36
|
<% if comment.pms_comment? && (@support_user || comment.metadata.created_by == @current_user_id) %>
|
|
37
37
|
<p>
|
|
38
|
-
<%= link_to('Edit', plan_my_stuff.edit_issue_comment_path(@issue.number, comment.id)) %>
|
|
38
|
+
<%= link_to('Edit', plan_my_stuff.edit_issue_comment_path(@issue.number, comment.id, repo: @issue.repo.full_name)) %>
|
|
39
39
|
</p>
|
|
40
40
|
<% end %>
|
|
41
41
|
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<%
|
|
2
|
+
persisted = project.persisted?
|
|
3
|
+
url =
|
|
4
|
+
if persisted
|
|
5
|
+
plan_my_stuff.project_path(project.number)
|
|
6
|
+
else
|
|
7
|
+
plan_my_stuff.projects_path
|
|
8
|
+
end
|
|
9
|
+
%>
|
|
10
|
+
<%= form_with(url: url, method: persisted ? :patch : :post, scope: :project) do |form| %>
|
|
11
|
+
<div>
|
|
12
|
+
<%= form.label(:title, 'Title') %>
|
|
13
|
+
<%= form.text_field(:title, value: project.title, required: true) %>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div>
|
|
17
|
+
<%= form.label(:description, 'Description') %>
|
|
18
|
+
<%= form.text_field(:description, value: project.description) %>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div>
|
|
22
|
+
<%= form.label(:readme, 'Readme') %>
|
|
23
|
+
<%= form.text_area(:readme, rows: 8, value: project.readme) %>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div>
|
|
27
|
+
<%= form.submit(persisted ? 'Update Project' : 'Create Project') %>
|
|
28
|
+
</div>
|
|
29
|
+
<% end %>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<h1><%= @project.title %></h1>
|
|
2
2
|
|
|
3
|
+
<p><%= link_to('Edit', plan_my_stuff.edit_project_path(@project.number)) %></p>
|
|
4
|
+
|
|
3
5
|
<% if @statuses.any? %>
|
|
4
6
|
<table>
|
|
5
7
|
<thead>
|
|
@@ -16,12 +18,12 @@
|
|
|
16
18
|
<% items = @items_by_status[status] || [] %>
|
|
17
19
|
<% items.each do |item| %>
|
|
18
20
|
<div style="border: 1px solid black; margin: 1em">
|
|
19
|
-
<%
|
|
20
|
-
<strong><%= link_to(item.title, plan_my_stuff.issue_path(item.number)) %></strong>
|
|
21
|
+
<% unless item.draft? %>
|
|
22
|
+
<strong><%= link_to(item.title, plan_my_stuff.issue_path(item.number, repo: item.repo.full_name)) %></strong>
|
|
21
23
|
<% else %>
|
|
22
24
|
<strong><%= item.title %></strong>
|
|
23
25
|
<% end %>
|
|
24
|
-
<%
|
|
26
|
+
<% unless item.draft? %>
|
|
25
27
|
<small>#<%= item.number %></small>
|
|
26
28
|
<% end %>
|
|
27
29
|
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
url: plan_my_stuff.unassign_project_item_path(@project.number, item.id),
|
|
47
49
|
method: :patch,
|
|
48
50
|
local: true,
|
|
49
|
-
style: 'display: inline',
|
|
51
|
+
html: { style: 'display: inline' },
|
|
50
52
|
) do |form|
|
|
51
53
|
%>
|
|
52
54
|
<%= form.hidden_field(:username, value: username) %>
|
data/config/routes.rb
CHANGED
|
@@ -13,7 +13,7 @@ PlanMyStuff::Engine.routes.draw do
|
|
|
13
13
|
delete 'labels/:name', to: 'labels#remove_from_issue', as: :remove_label
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
resources :projects,
|
|
16
|
+
resources :projects, except: %i[destroy] do
|
|
17
17
|
resources :items, only: %i[create], controller: 'project_items' do
|
|
18
18
|
member do
|
|
19
19
|
patch :move
|
|
@@ -100,7 +100,16 @@ PMS.configure do |config|
|
|
|
100
100
|
# Supported types: :string, :integer, :boolean, :array, :hash
|
|
101
101
|
# required: true means the key must be present (value can be nil, [], etc.)
|
|
102
102
|
#
|
|
103
|
+
# Shared fields (available on both issues and comments):
|
|
103
104
|
config.custom_fields = {
|
|
104
|
-
notification_recipients: { type: :array, required: true },
|
|
105
|
+
# notification_recipients: { type: :array, required: true },
|
|
105
106
|
}
|
|
107
|
+
|
|
108
|
+
# Issue-only fields (merged on top of shared, context wins on conflicts):
|
|
109
|
+
# config.issue_custom_fields = {
|
|
110
|
+
# ticket_type: { type: :string, required: true },
|
|
111
|
+
# }
|
|
112
|
+
|
|
113
|
+
# Comment-only fields (merged on top of shared, context wins on conflicts):
|
|
114
|
+
# config.comment_custom_fields = {}
|
|
106
115
|
end
|
|
@@ -8,6 +8,19 @@ module PlanMyStuff
|
|
|
8
8
|
class ApplicationRecord
|
|
9
9
|
include ActiveModel::Model
|
|
10
10
|
|
|
11
|
+
class << self
|
|
12
|
+
# Reads a field from an object that may respond to method calls or hash access.
|
|
13
|
+
#
|
|
14
|
+
# @param obj [Object]
|
|
15
|
+
# @param field [Symbol]
|
|
16
|
+
#
|
|
17
|
+
# @return [Object]
|
|
18
|
+
#
|
|
19
|
+
def read_field(obj, field)
|
|
20
|
+
obj.respond_to?(field) ? obj.public_send(field) : obj[field]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
11
24
|
def initialize(**)
|
|
12
25
|
super
|
|
13
26
|
@persisted = false
|
|
@@ -33,7 +46,30 @@ module PlanMyStuff
|
|
|
33
46
|
# @return [Object]
|
|
34
47
|
#
|
|
35
48
|
def read_field(obj, field)
|
|
36
|
-
|
|
49
|
+
self.class.read_field(obj, field)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Reads a field from an object, returning nil if the field does not exist.
|
|
53
|
+
#
|
|
54
|
+
# @param obj [Object]
|
|
55
|
+
# @param field [Symbol]
|
|
56
|
+
#
|
|
57
|
+
# @return [Object, nil]
|
|
58
|
+
#
|
|
59
|
+
def safe_read_field(obj, field)
|
|
60
|
+
read_field(obj, field)
|
|
61
|
+
rescue NameError
|
|
62
|
+
nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @return [Time, nil]
|
|
66
|
+
def parse_github_time(value)
|
|
67
|
+
return if value.nil?
|
|
68
|
+
return value.utc if value.is_a?(Time)
|
|
69
|
+
|
|
70
|
+
Time.parse(value.to_s).utc
|
|
71
|
+
rescue ArgumentError
|
|
72
|
+
nil
|
|
37
73
|
end
|
|
38
74
|
end
|
|
39
75
|
end
|