coplan-engine 0.1.3 → 0.2.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/app/assets/stylesheets/coplan/application.css +212 -85
- data/app/controllers/coplan/api/v1/comments_controller.rb +7 -7
- data/app/controllers/coplan/comment_threads_controller.rb +26 -72
- data/app/controllers/coplan/plans_controller.rb +1 -3
- data/app/javascript/controllers/coplan/comment_form_controller.js +14 -0
- data/app/javascript/controllers/coplan/comment_nav_controller.js +134 -0
- data/app/javascript/controllers/coplan/text_selection_controller.js +99 -161
- data/app/jobs/coplan/automated_review_job.rb +4 -4
- data/app/models/coplan/comment_thread.rb +13 -7
- data/app/policies/coplan/comment_thread_policy.rb +1 -1
- data/app/views/coplan/comment_threads/_new_comment_form.html.erb +2 -1
- data/app/views/coplan/comment_threads/_reply_form.html.erb +2 -1
- data/app/views/coplan/comment_threads/_thread.html.erb +3 -6
- data/app/views/coplan/comment_threads/_thread_popover.html.erb +58 -0
- data/app/views/coplan/plans/show.html.erb +22 -30
- data/app/views/layouts/coplan/application.html.erb +3 -0
- data/config/routes.rb +2 -2
- data/db/migrate/20260320145453_migrate_comment_thread_statuses.rb +31 -0
- data/lib/coplan/version.rb +1 -1
- metadata +5 -2
- data/app/javascript/controllers/coplan/tabs_controller.js +0 -18
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<div class="plan-content card">
|
|
6
6
|
<% if @plan.current_content.present? %>
|
|
7
7
|
<div class="plan-layout" data-controller="coplan--text-selection" data-coplan--text-selection-plan-id-value="<%= @plan.id %>">
|
|
8
|
+
<div class="plan-layout__margin" data-coplan--text-selection-target="margin"></div>
|
|
8
9
|
<div class="plan-layout__content" data-coplan--text-selection-target="content">
|
|
9
10
|
<%= render_markdown(@plan.current_content) %>
|
|
10
11
|
|
|
@@ -13,39 +14,14 @@
|
|
|
13
14
|
💬 Comment
|
|
14
15
|
</button>
|
|
15
16
|
</div>
|
|
16
|
-
</div>
|
|
17
17
|
|
|
18
|
-
<div class="plan-layout__sidebar">
|
|
19
18
|
<%= render partial: "coplan/comment_threads/new_comment_form", locals: { plan: @plan } %>
|
|
19
|
+
</div>
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</button>
|
|
26
|
-
<button class="comment-tab" data-coplan--tabs-target="tab" data-action="coplan--tabs#switch coplan--text-selection#repositionThreads" data-index="1">
|
|
27
|
-
Resolved <span class="comment-tab__count" id="resolved-thread-count"><%= @archived_threads.size if @archived_threads.any? %></span>
|
|
28
|
-
</button>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<div class="comment-tabs__panel" data-coplan--tabs-target="panel">
|
|
32
|
-
<div class="comment-threads-list" id="comment-threads">
|
|
33
|
-
<% @active_threads.each do |thread| %>
|
|
34
|
-
<%= render partial: "coplan/comment_threads/thread", locals: { thread: thread, plan: @plan, current_user: current_user } %>
|
|
35
|
-
<% end %>
|
|
36
|
-
<p class="text-sm text-muted" id="open-threads-empty" <% if @active_threads.any? %>style="display: none;"<% end %>>No open comments.</p>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
<div class="comment-tabs__panel" data-coplan--tabs-target="panel" style="display: none;">
|
|
41
|
-
<div class="comment-threads-list" id="resolved-comment-threads">
|
|
42
|
-
<% @archived_threads.each do |thread| %>
|
|
43
|
-
<%= render partial: "coplan/comment_threads/thread", locals: { thread: thread, plan: @plan, current_user: current_user } %>
|
|
44
|
-
<% end %>
|
|
45
|
-
<p class="text-sm text-muted" id="resolved-threads-empty" <% if @archived_threads.any? %>style="display: none;"<% end %>>No resolved comments.</p>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
21
|
+
<div id="plan-threads" data-coplan--text-selection-target="threads">
|
|
22
|
+
<% @threads.select(&:anchored?).each do |thread| %>
|
|
23
|
+
<%= render partial: "coplan/comment_threads/thread_popover", locals: { thread: thread, plan: @plan, current_user: current_user } %>
|
|
24
|
+
<% end %>
|
|
49
25
|
</div>
|
|
50
26
|
</div>
|
|
51
27
|
<% else %>
|
|
@@ -54,3 +30,19 @@
|
|
|
54
30
|
</div>
|
|
55
31
|
<% end %>
|
|
56
32
|
</div>
|
|
33
|
+
|
|
34
|
+
<% open_count = @threads.count(&:open?) %>
|
|
35
|
+
<% if @threads.any? %>
|
|
36
|
+
<div class="comment-toolbar" data-controller="coplan--comment-nav" data-coplan--comment-nav-plan-id-value="<%= @plan.id %>">
|
|
37
|
+
<span class="comment-toolbar__count">💬 <%= open_count %> open</span>
|
|
38
|
+
<div class="comment-toolbar__nav">
|
|
39
|
+
<button class="btn btn--secondary btn--sm" data-action="coplan--comment-nav#prev" title="Previous comment">↑</button>
|
|
40
|
+
<span class="comment-toolbar__position" data-coplan--comment-nav-target="position"></span>
|
|
41
|
+
<button class="btn btn--secondary btn--sm" data-action="coplan--comment-nav#next" title="Next comment">↓</button>
|
|
42
|
+
</div>
|
|
43
|
+
<label class="comment-toolbar__toggle">
|
|
44
|
+
<input type="checkbox" data-action="coplan--comment-nav#toggleResolved" data-coplan--comment-nav-target="resolvedToggle">
|
|
45
|
+
Show resolved (<%= @threads.count { |t| !t.open? } %>)
|
|
46
|
+
</label>
|
|
47
|
+
</div>
|
|
48
|
+
<% end %>
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
<%= csrf_meta_tags %>
|
|
7
7
|
<%= csp_meta_tag %>
|
|
8
8
|
<%= yield :head %>
|
|
9
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
+
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
9
12
|
<%= stylesheet_link_tag "coplan/application", "data-turbo-track": "reload" %>
|
|
10
13
|
<%= javascript_importmap_tags %>
|
|
11
14
|
</head>
|
data/config/routes.rb
CHANGED
|
@@ -7,7 +7,7 @@ CoPlan::Engine.routes.draw do
|
|
|
7
7
|
member do
|
|
8
8
|
patch :resolve
|
|
9
9
|
patch :accept
|
|
10
|
-
patch :
|
|
10
|
+
patch :discard
|
|
11
11
|
patch :reopen
|
|
12
12
|
end
|
|
13
13
|
resources :comments, only: [:create]
|
|
@@ -31,7 +31,7 @@ CoPlan::Engine.routes.draw do
|
|
|
31
31
|
resources :comments, only: [:create], controller: "comments" do
|
|
32
32
|
post :reply, on: :member
|
|
33
33
|
patch :resolve, on: :member
|
|
34
|
-
patch :
|
|
34
|
+
patch :discard, on: :member
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class MigrateCommentThreadStatuses < ActiveRecord::Migration[8.0]
|
|
2
|
+
def up
|
|
3
|
+
# open → pending (default for new comments from non-authors)
|
|
4
|
+
# accepted → resolved (collapse accepted into resolved)
|
|
5
|
+
# dismissed → discarded (rename)
|
|
6
|
+
# resolved stays resolved
|
|
7
|
+
#
|
|
8
|
+
# We also add "todo" as a new status (author agrees with feedback).
|
|
9
|
+
# Existing "open" threads become "pending" since we can't determine authorship here.
|
|
10
|
+
execute <<~SQL
|
|
11
|
+
UPDATE coplan_comment_threads SET status = 'pending' WHERE status = 'open'
|
|
12
|
+
SQL
|
|
13
|
+
execute <<~SQL
|
|
14
|
+
UPDATE coplan_comment_threads SET status = 'discarded' WHERE status = 'dismissed'
|
|
15
|
+
SQL
|
|
16
|
+
execute <<~SQL
|
|
17
|
+
UPDATE coplan_comment_threads SET status = 'resolved' WHERE status = 'accepted'
|
|
18
|
+
SQL
|
|
19
|
+
change_column_default :coplan_comment_threads, :status, "pending"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def down
|
|
23
|
+
change_column_default :coplan_comment_threads, :status, "open"
|
|
24
|
+
execute <<~SQL
|
|
25
|
+
UPDATE coplan_comment_threads SET status = 'open' WHERE status IN ('pending', 'todo')
|
|
26
|
+
SQL
|
|
27
|
+
execute <<~SQL
|
|
28
|
+
UPDATE coplan_comment_threads SET status = 'dismissed' WHERE status = 'discarded'
|
|
29
|
+
SQL
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/coplan/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: coplan-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Block
|
|
@@ -159,9 +159,10 @@ files:
|
|
|
159
159
|
- app/helpers/coplan/application_helper.rb
|
|
160
160
|
- app/helpers/coplan/comments_helper.rb
|
|
161
161
|
- app/helpers/coplan/markdown_helper.rb
|
|
162
|
+
- app/javascript/controllers/coplan/comment_form_controller.js
|
|
163
|
+
- app/javascript/controllers/coplan/comment_nav_controller.js
|
|
162
164
|
- app/javascript/controllers/coplan/dropdown_controller.js
|
|
163
165
|
- app/javascript/controllers/coplan/line_selection_controller.js
|
|
164
|
-
- app/javascript/controllers/coplan/tabs_controller.js
|
|
165
166
|
- app/javascript/controllers/coplan/text_selection_controller.js
|
|
166
167
|
- app/jobs/coplan/application_job.rb
|
|
167
168
|
- app/jobs/coplan/automated_review_job.rb
|
|
@@ -197,6 +198,7 @@ files:
|
|
|
197
198
|
- app/views/coplan/comment_threads/_new_comment_form.html.erb
|
|
198
199
|
- app/views/coplan/comment_threads/_reply_form.html.erb
|
|
199
200
|
- app/views/coplan/comment_threads/_thread.html.erb
|
|
201
|
+
- app/views/coplan/comment_threads/_thread_popover.html.erb
|
|
200
202
|
- app/views/coplan/comments/_comment.html.erb
|
|
201
203
|
- app/views/coplan/dashboard/show.html.erb
|
|
202
204
|
- app/views/coplan/plan_versions/index.html.erb
|
|
@@ -216,6 +218,7 @@ files:
|
|
|
216
218
|
- config/routes.rb
|
|
217
219
|
- db/migrate/20260226200000_create_coplan_schema.rb
|
|
218
220
|
- db/migrate/20260313210000_expand_content_markdown_to_mediumtext.rb
|
|
221
|
+
- db/migrate/20260320145453_migrate_comment_thread_statuses.rb
|
|
219
222
|
- lib/coplan.rb
|
|
220
223
|
- lib/coplan/configuration.rb
|
|
221
224
|
- lib/coplan/engine.rb
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Controller } from "@hotwired/stimulus"
|
|
2
|
-
|
|
3
|
-
export default class extends Controller {
|
|
4
|
-
static targets = ["tab", "panel"]
|
|
5
|
-
static classes = ["active"]
|
|
6
|
-
|
|
7
|
-
switch(event) {
|
|
8
|
-
const index = parseInt(event.currentTarget.dataset.index)
|
|
9
|
-
|
|
10
|
-
this.tabTargets.forEach((tab, i) => {
|
|
11
|
-
tab.classList.toggle(this.activeClass, i === index)
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
this.panelTargets.forEach((panel, i) => {
|
|
15
|
-
panel.style.display = i === index ? "" : "none"
|
|
16
|
-
})
|
|
17
|
-
}
|
|
18
|
-
}
|