Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/controllers/comments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def set_commentable
@commentable = Organization.find(params[:organization_id])
elsif params[:event_registration_id]
@commentable = EventRegistration.find(params[:event_registration_id])
elsif params[:workshop_id]
@commentable = Workshop.find(params[:workshop_id])
else
redirect_to root_path, alert: "Invalid commentable resource"
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/event_registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def update
authorize! @event_registration
@event_registration.assign_attributes(event_registration_update_params)
@event_registration.comments.select(&:new_record?).each { |c| c.created_by = current_user; c.updated_by = current_user }
@event_registration.comments.select(&:changed?).each { |c| c.updated_by = current_user }
@event_registration.comments.select { |c| c.persisted? && c.body_changed? }.each { |c| c.updated_by = current_user }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only want to update updated_by when content of comment changes


if @event_registration.save
respond_to do |format|
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/organizations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def update
authorize! @organization
@organization.assign_attributes(organization_params)
@organization.comments.select(&:new_record?).each { |c| c.created_by = current_user; c.updated_by = current_user }
@organization.comments.select(&:changed?).each { |c| c.updated_by = current_user }
@organization.comments.select { |c| c.persisted? && c.body_changed? }.each { |c| c.updated_by = current_user }

if @organization.save
assign_associations(@organization) if params.dig(:organization, :category_ids)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/people_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def update

@person.assign_attributes(person_params)
@person.comments.select(&:new_record?).each { |c| c.created_by = current_user; c.updated_by = current_user }
@person.comments.select(&:changed?).each { |c| c.updated_by = current_user }
@person.comments.select { |c| c.persisted? && c.body_changed? }.each { |c| c.updated_by = current_user }

if @person.save
assign_associations(@person) if params.dig(:person, :category_ids)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def update
@user.assign_attributes(user_params.except(:password, :password_confirmation))
@user.updated_by = current_user
@user.comments.select(&:new_record?).each { |c| c.created_by = current_user; c.updated_by = current_user }
@user.comments.select(&:changed?).each { |c| c.updated_by = current_user }
@user.comments.select { |c| c.persisted? && c.body_changed? }.each { |c| c.updated_by = current_user }

# Suppress Devise's automatic reconfirmation email so the interstitial can control it
@user.skip_confirmation_notification!
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/workshops_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,12 @@ def update
authorize! @workshop
success = false

@workshop.assign_attributes(workshop_params)
@workshop.comments.select(&:new_record?).each { |c| c.created_by = current_user; c.updated_by = current_user }
@workshop.comments.select { |c| c.persisted? && c.body_changed? }.each { |c| c.updated_by = current_user }

Workshop.transaction do
if @workshop.update(workshop_params)
if @workshop.save
assign_associations(@workshop)
success = true
end
Expand Down Expand Up @@ -288,7 +292,8 @@ def workshop_params
gallery_assets_attributes: [ :id, :file, :_destroy ],
workshop_series_children_attributes: [ :id, :workshop_child_id, :workshop_parent_id, :theme_name,
:series_description, :series_description_spanish,
:position, :_destroy ]
:position, :_destroy ],
comments_attributes: [ :id, :body ]
)
end
end
2 changes: 2 additions & 0 deletions app/models/workshop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def self.mentionable_rich_text_fields
belongs_to :workshop_idea, optional: true

has_many :bookmarks, as: :bookmarkable, dependent: :destroy
has_many :comments, -> { newest_first }, as: :commentable, dependent: :destroy
has_many :categorizable_items, dependent: :destroy, inverse_of: :categorizable, as: :categorizable
has_many :quotable_item_quotes, as: :quotable, dependent: :destroy
has_many :associated_resources, class_name: "Resource", foreign_key: "workshop_id", dependent: :restrict_with_error
Expand Down Expand Up @@ -135,6 +136,7 @@ def self.mentionable_rich_text_fields
reject_if: proc { |attributes| attributes["workshop_child_id"].blank? },
allow_destroy: true
accepts_nested_attributes_for :workshop_variations, reject_if: proc { |object| object.nil? }
accepts_nested_attributes_for :comments, reject_if: proc { |attrs| attrs["body"].blank? }


# Scopes
Expand Down
19 changes: 7 additions & 12 deletions app/views/comments/_comment_fields.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,18 @@
<% updated_color = show_updated ? label_colors[(updated_user.id || 0) % label_colors.length] : nil %>
<% current_color = label_colors[(current_user&.id || 0) % label_colors.length] %>
<div class="nested-fields" data-paginated-fields-target="item">
<%= f.hidden_field :id if f.object.persisted? %>
<% if f.object.persisted? %>
<div class="comment-view flex items-center mb-3 pl-4 gap-x-1">
<span class="text-xs text-gray-400 whitespace-nowrap shrink-0">
<%= f.object.created_at.strftime("%-m/%-d/%Y %-I:%M %p") %>
</span>
<span class="inline-flex items-center gap-x-1 w-20 shrink-0">
<% if show_updated %>
<% if created_initials.present? %>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default" title="<%= created_name %>"><%= created_initials %></span>
<% else %>
test
<% end %>
<span class="<%= updated_color[0] %> <%= updated_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default" title="Edited by <%= updated_name %>"><%= updated_initials %></span>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-1/2 text-center" title="<%= created_name %>"><%= created_initials.presence || "--" %></span>
<span class="<%= updated_color[0] %> <%= updated_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-1/2 text-center" title="Edited by <%= updated_name %>"><%= updated_initials.presence || "--" %></span>
<% else %>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-full text-left" title="<%= created_name %>"><%= truncate(created_first_name.presence || "Unknown", length: 10, omission: "..") %></span>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-full text-left" title="<%= created_name %>"><%= truncate(created_first_name.presence || "--", length: 10, omission: "..") %></span>
<% end %>
</span>
<span class="text-sm text-gray-900 comment-body truncate" title="<%= f.object.body %>">
Expand All @@ -57,12 +54,10 @@
</span>
<span class="inline-flex items-center gap-x-1 w-20 shrink-0 mt-2">
<% if show_updated %>
<% if created_initials.present? %>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default" title="<%= created_name %>"><%= created_initials %></span>
<% end %>
<span class="<%= updated_color[0] %> <%= updated_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default" title="Edited by <%= updated_name %>"><%= updated_initials %></span>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-1/2 text-center" title="<%= created_name %>"><%= created_initials.presence || "--" %></span>
<span class="<%= updated_color[0] %> <%= updated_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-1/2 text-center" title="Edited by <%= updated_name %>"><%= updated_initials.presence || "--" %></span>
<% else %>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-full text-left" title="<%= created_name %>"><%= truncate(created_first_name.to_s, length: 10, omission: "..") %></span>
<span class="<%= created_color[0] %> <%= created_color[1] %> text-xs px-1.5 py-0.5 rounded cursor-default truncate w-full text-left" title="<%= created_name %>"><%= truncate(created_first_name.presence || "--", length: 10, omission: "..") %></span>
<% end %>
</span>
<div class="grow">
Expand Down
64 changes: 63 additions & 1 deletion app/views/workshops/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,71 @@
</div>
</div>
</div>

<div class="images-section" data-controller="dropdown">
<button
type="button"
id="images_button"
class="
flex items-center justify-between cursor-pointer w-full
bg-gray-500 text-white hover:bg-gray-300 px-3 py-2 rounded-t-md
"
data-action="dropdown#toggle"
data-dropdown-payload-param='[{"images":"hidden"}, {"images_arrow":"rotate-180"}, {"images_button":"rounded-md rounded-t-md"}]'
>
Images/attachments
<svg
id="images_arrow"
class="w-6 h-6 shrink-0 rotate-180"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
</button>

<div id="images" class="border border-gray-300 p-4 rounded-b-md">
<%= render "shared/form_image_fields", f: f, include_primary_asset: true %>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved images into a toggle

</div>
</div>
</div>

<%= render "shared/form_image_fields", f: f, include_primary_asset: true %>
<% if f.object.persisted? %>
<% if allowed_to?(:manage?, Comment) %>
<div class="admin-only bg-blue-100 form-group p-3 space-y-4 mt-6 rounded-md" id="comments-section">
<div class="font-semibold text-gray-700 mb-2">Comments</div>

<div class="admin-only bg-blue-100 rounded-lg border border-gray-200 p-4 mb-4 shadow-sm"
data-controller="paginated-fields comment-edit-toggle"
data-paginated-fields-per-page-value="5">
<%= f.simple_fields_for :comments do |cf| %>
<%= render "comments/comment_fields", f: cf %>
<% end %>

<div data-paginated-fields-target="nav"></div>

<button type="button"
class="text-sm text-gray-400 hover:text-blue-600 underline cursor-pointer whitespace-nowrap"
style="float:right"
data-action="click->comment-edit-toggle#toggle">
<span data-comment-edit-toggle-target="editLabel">Edit Comments</span>
<span data-comment-edit-toggle-target="viewLabel" style="display:none">Done Editing</span>
</button>
<%= link_to_add_association "➕ Add Comment",
f,
:comments,
partial: "comments/comment_fields",
class: "btn btn-secondary-outline" %>
</div>
</div>
<% end %>
<% end %>

<div class="action-buttons mt-8 flex justify-center gap-3">
<% if allowed_to?(:destroy?, f.object) %>
<%= link_to "Delete", @workshop, class: "btn btn-danger-outline",
Expand Down
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@
resources :workshop_log_creation_wizard
resources :workshop_variation_ideas
resources :workshop_variations
resources :workshops
resources :workshops do
resources :comments, only: [ :index, :create ]
end

resources :workshop_mentions, only: [ :index ]
resources :resource_mentions, only: [ :index ]
Expand Down
4 changes: 4 additions & 0 deletions spec/factories/comments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@
trait :for_event_registration do
association :commentable, factory: :event_registration
end

trait :for_workshop do
association :commentable, factory: :workshop
end
end
end
7 changes: 7 additions & 0 deletions spec/models/comment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
expect(comment.commentable).to eq(event_registration)
expect(event_registration.comments).to include(comment)
end

it 'can be associated with a Workshop' do
workshop = create(:workshop)
comment = create(:comment, commentable: workshop, body: "Workshop comment")
expect(comment.commentable).to eq(workshop)
expect(workshop.comments).to include(comment)
end
end

describe 'scopes' do
Expand Down
2 changes: 1 addition & 1 deletion spec/requests/workshops_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
it "handles RecordNotUnique gracefully" do
workshop = create(:workshop)

allow_any_instance_of(Workshop).to receive(:update).and_raise(
allow_any_instance_of(Workshop).to receive(:save).and_raise(
ActiveRecord::RecordNotUnique.new("Duplicate entry")
)

Expand Down
1 change: 1 addition & 0 deletions spec/system/events_show_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@
expect(page).not_to have_button("Register")

# "View Registration" is a clickable link to the registration show page
expect(page).to have_link("View Registration")
registration = EventRegistration.last
expect(page).to have_link("View Registration", href: registration_ticket_path(registration.slug))
end
Expand Down
Loading