activeadmin_annotations 0.1.1 → 0.1.2

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/CODE_OF_CONDUCT.md +14 -19
  4. data/CONTRIBUTING.md +9 -15
  5. data/GOVERNANCE.md +10 -14
  6. data/README.md +24 -7
  7. data/SECURITY.md +14 -16
  8. data/activeadmin_annotations.gemspec +2 -2
  9. data/admin/annotation_reviews.rb +14 -6
  10. data/admin/annotations.rb +33 -13
  11. data/app/assets/controllers/activeadmin_annotations/annotation_client.js +44 -0
  12. data/app/assets/controllers/activeadmin_annotations/annotation_list.js +29 -0
  13. data/app/assets/controllers/activeadmin_annotations/annotator_controller.js +45 -370
  14. data/app/assets/controllers/activeadmin_annotations/composer.js +179 -0
  15. data/app/assets/controllers/activeadmin_annotations/highlights.js +76 -0
  16. data/app/assets/controllers/activeadmin_annotations/selection.js +73 -0
  17. data/app/assets/javascripts/activeadmin_annotations/annotator_logic.mjs +73 -0
  18. data/app/assets/stylesheets/activeadmin_annotations.css +15 -0
  19. data/app/helpers/active_admin/annotations/panel_helper.rb +15 -8
  20. data/app/models/active_admin/annotations/review.rb +7 -2
  21. data/app/services/active_admin/annotations/review_service.rb +34 -27
  22. data/app/views/active_admin/annotations/_panel.html.erb +15 -2
  23. data/db/migrate/20260617120000_create_activeadmin_annotations_tables.rb +27 -10
  24. data/db/migrate/20260706150000_add_metadata_json_gin_index_to_annotation_reviews.rb +1 -1
  25. data/db/migrate/20260710120000_add_panel_query_index_to_annotation_spans.rb +1 -1
  26. data/lib/activeadmin/annotations/copy_text.rb +0 -1
  27. data/lib/activeadmin/annotations/engine.rb +16 -1
  28. data/lib/activeadmin/annotations/exporter.rb +1 -1
  29. data/lib/activeadmin/annotations/panel_html.rb +21 -0
  30. data/lib/activeadmin/annotations/review_access.rb +13 -1
  31. data/lib/activeadmin/annotations/review_panel.rb +9 -6
  32. data/lib/activeadmin/annotations/span_create.rb +70 -0
  33. data/lib/activeadmin/annotations/version.rb +1 -1
  34. data/lib/activeadmin_annotations.rb +2 -0
  35. metadata +12 -4
@@ -69,7 +69,8 @@ module ActiveAdmin::Annotations
69
69
  display_version: display_version,
70
70
  annotations: annotations,
71
71
  content_stale: false,
72
- advance_review_url: nil
72
+ advance_review_url: nil,
73
+ readonly: review.blank? || display_version != review.content_revision_version
73
74
  )
74
75
  end
75
76
 
@@ -84,7 +85,7 @@ module ActiveAdmin::Annotations
84
85
  context = @context_builder.call(content_subject)
85
86
  digest = Context.digest_for(context)
86
87
 
87
- review = ReviewService.find_or_sync_review!(
88
+ review = ReviewService.preview_review(
88
89
  subject: @subject,
89
90
  reviewer: @reviewer,
90
91
  context: context,
@@ -107,11 +108,12 @@ module ActiveAdmin::Annotations
107
108
  display_version: review.content_revision_version,
108
109
  annotations: annotations,
109
110
  content_stale: review.context_stale?,
110
- advance_review_url: revision_enabled ? @advance_review_url : nil
111
+ advance_review_url: revision_enabled ? @advance_review_url : nil,
112
+ readonly: false
111
113
  )
112
114
  end
113
115
 
114
- def render_panel(review:, content_subject:, revision_enabled:, latest_version:, display_version:, annotations:, content_stale:, advance_review_url:)
116
+ def render_panel(review:, content_subject:, revision_enabled:, latest_version:, display_version:, annotations:, content_stale:, advance_review_url:, readonly: false)
115
117
  context = @context_builder.call(content_subject)
116
118
 
117
119
  @view_context.helpers.activeadmin_annotations_panel(
@@ -129,12 +131,13 @@ module ActiveAdmin::Annotations
129
131
  annotations: annotations,
130
132
  review: review,
131
133
  categories: @categories,
132
- category_label: @category_label
134
+ category_label: @category_label,
135
+ readonly: readonly
133
136
  )
134
137
  end
135
138
 
136
139
  def annotations_for_review(review:, revision_enabled:, display_version:)
137
- return [] if review.blank?
140
+ return [] unless review&.persisted?
138
141
 
139
142
  scope = review.annotations.where(field_name: @field).order(:created_at)
140
143
  return scope unless revision_enabled
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAdmin::Annotations
4
+ class SpanCreate
5
+ class ReadOnly < StandardError; end
6
+
7
+ def self.review_for!(params:, reviewer:)
8
+ new(params: params, reviewer: reviewer).review
9
+ end
10
+
11
+ def initialize(params:, reviewer:)
12
+ @params = params
13
+ @reviewer = reviewer
14
+ end
15
+
16
+ def review
17
+ resolved = existing_review_or_persist_from_subject
18
+ reject_read_only!(resolved)
19
+ resolved
20
+ end
21
+
22
+ private
23
+
24
+ def existing_review_or_persist_from_subject
25
+ review_id = annotation_hash[:annotation_review_id]
26
+ if review_id.present?
27
+ ReviewAccess.review_for_span_create!(review_id: review_id, reviewer: @reviewer)
28
+ else
29
+ persist_from_subject!
30
+ end
31
+ end
32
+
33
+ def persist_from_subject!
34
+ raise ReviewAccess::Forbidden, "Review access denied" if @reviewer.blank?
35
+
36
+ subject = ReviewAccess.subject_for_span_create!(
37
+ subject_type: annotation_hash[:subject_type],
38
+ subject_id: annotation_hash[:subject_id]
39
+ )
40
+ revision_enabled = ContentRevision.enabled_for?(subject)
41
+ ReviewService.find_or_sync_review!(
42
+ subject: subject,
43
+ reviewer: @reviewer,
44
+ context: context_from_params,
45
+ context_digest: annotation_hash[:context_digest],
46
+ content_revision_version: revision_enabled ? ContentRevision.current_version_for(subject) : 0,
47
+ content_revision_enabled: revision_enabled
48
+ )
49
+ end
50
+
51
+ def reject_read_only!(review)
52
+ return unless annotation_hash.key?(:displayed_content_revision_version)
53
+ return if annotation_hash[:displayed_content_revision_version].to_i == review.content_revision_version
54
+
55
+ raise ReadOnly, "This version is read-only."
56
+ end
57
+
58
+ def context_from_params
59
+ context = annotation_hash[:context_json].presence || {}
60
+ context = context.to_unsafe_h if context.respond_to?(:to_unsafe_h)
61
+ context
62
+ end
63
+
64
+ def annotation_hash
65
+ raw = @params[:annotation] || @params["annotation"] || {}
66
+ raw = raw.to_unsafe_h if raw.respond_to?(:to_unsafe_h)
67
+ raw.respond_to?(:with_indifferent_access) ? raw.with_indifferent_access : raw
68
+ end
69
+ end
70
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveAdmin
4
4
  module Annotations
5
- VERSION = "0.1.1"
5
+ VERSION = "0.1.2"
6
6
  end
7
7
  end
@@ -9,5 +9,7 @@ require "activeadmin/annotations/exporter"
9
9
  require "activeadmin/annotations/copy_text"
10
10
  require "activeadmin/annotations/content_revision"
11
11
  require "activeadmin/annotations/review_access"
12
+ require "activeadmin/annotations/span_create"
13
+ require "activeadmin/annotations/panel_html"
12
14
  require "activeadmin/annotations/review_panel"
13
15
  require "activeadmin/annotations/engine"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeadmin_annotations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Makarov
@@ -309,14 +309,14 @@ dependencies:
309
309
  requirements:
310
310
  - - "~>"
311
311
  - !ruby/object:Gem::Version
312
- version: '3'
312
+ version: '4'
313
313
  type: :development
314
314
  prerelease: false
315
315
  version_requirements: !ruby/object:Gem::Requirement
316
316
  requirements:
317
317
  - - "~>"
318
318
  - !ruby/object:Gem::Version
319
- version: '3'
319
+ version: '4'
320
320
  description: Collect text highlights and comments inside a bounded ActiveAdmin block,
321
321
  with optional review context, content revision pinning, and JSONL export.
322
322
  email:
@@ -335,8 +335,14 @@ files:
335
335
  - activeadmin_annotations.gemspec
336
336
  - admin/annotation_reviews.rb
337
337
  - admin/annotations.rb
338
+ - app/assets/controllers/activeadmin_annotations/annotation_client.js
339
+ - app/assets/controllers/activeadmin_annotations/annotation_list.js
338
340
  - app/assets/controllers/activeadmin_annotations/annotator_controller.js
339
341
  - app/assets/controllers/activeadmin_annotations/clipboard_controller.js
342
+ - app/assets/controllers/activeadmin_annotations/composer.js
343
+ - app/assets/controllers/activeadmin_annotations/highlights.js
344
+ - app/assets/controllers/activeadmin_annotations/selection.js
345
+ - app/assets/javascripts/activeadmin_annotations/annotator_logic.mjs
340
346
  - app/assets/stylesheets/activeadmin_annotations.css
341
347
  - app/helpers/active_admin/annotations/panel_helper.rb
342
348
  - app/models/active_admin/annotations/annotation.rb
@@ -358,8 +364,10 @@ files:
358
364
  - lib/activeadmin/annotations/copy_text.rb
359
365
  - lib/activeadmin/annotations/engine.rb
360
366
  - lib/activeadmin/annotations/exporter.rb
367
+ - lib/activeadmin/annotations/panel_html.rb
361
368
  - lib/activeadmin/annotations/review_access.rb
362
369
  - lib/activeadmin/annotations/review_panel.rb
370
+ - lib/activeadmin/annotations/span_create.rb
363
371
  - lib/activeadmin/annotations/version.rb
364
372
  - lib/activeadmin_annotations.rb
365
373
  - sig/activeadmin/annotations.rbs
@@ -380,7 +388,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
380
388
  requirements:
381
389
  - - ">="
382
390
  - !ruby/object:Gem::Version
383
- version: 3.2.0
391
+ version: '3.4'
384
392
  required_rubygems_version: !ruby/object:Gem::Requirement
385
393
  requirements:
386
394
  - - ">="