Skip to content

fix: fix bulk inline edit mode for event activities#818

Open
priscila-moneo wants to merge 1 commit intomasterfrom
fix/fix-bulk-inline-edit-mode-event-activities
Open

fix: fix bulk inline edit mode for event activities#818
priscila-moneo wants to merge 1 commit intomasterfrom
fix/fix-bulk-inline-edit-mode-event-activities

Conversation

@priscila-moneo
Copy link

@priscila-moneo priscila-moneo commented Mar 10, 2026

ref: https://app.clickup.com/t/86b8rq0hj

  • Removed unintended media-material saves from Events bulk edit flow (no afterUpdate media side effects).
  • Kept media uploads as non-editable in bulk mode (display-only behavior).
  • Fixed media material navigation to always use the event row id, avoiding event/presentation id ambiguity.
  • Excluded speakers from bulk update payloads to prevent “Speakers are mandatory” validation errors.
  • Added regression tests for bulk behavior, media link behavior (including missing row id guard), and editable-table render consistency.

Summary by CodeRabbit

  • Bug Fixes

    • Improved robustness of event data normalization for speakers and sponsors.
  • Tests

    • Added comprehensive test coverage for bulk event updates, editable table functionality, event material submissions, and event list page interactions.

@priscila-moneo priscila-moneo force-pushed the fix/fix-bulk-inline-edit-mode-event-activities branch from a27bc30 to 9520b71 Compare March 10, 2026 13:44
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

📝 Walkthrough

Walkthrough

This PR introduces comprehensive unit tests for event normalization and table component behaviors, updates event action logic to handle speakers and sponsors more robustly with type checking and filtering, passes full row context to table render callbacks, and refactors media_uploads rendering in the event list page while removing the afterUpdate hook integration.

Changes

Cohort / File(s) Summary
Event Normalization
src/actions/event-actions.js, src/actions/__tests__/event-actions-bulk.test.js
Enhanced normalizeEvent to conditionally map sponsors and speakers (preserve numbers, extract id from objects, filter falsy values). Updated normalizeBulkEvents to exclude speakers field. New test verifies bulk normalization flattens related objects and excludes speakers.
Table Row Rendering
src/components/tables/editable-table/EditableTableRow.js
Modified render callbacks to pass full row object as second argument: col.render(row[col.columnKey], row) in both editable and non-editable branches.
EditableTable Tests
src/components/tables/editable-table/__tests__/EditableTable.test.js
Added tests validating bulk update behavior: confirms updateData is called with summit ID and row array, and verifies afterUpdate hook invocation when configured.
Event List Page Refactoring
src/pages/events/summit-event-list-page.js
Removed saveEventMaterial import and afterUpdate hook from EditableTable. Refactored media_uploads render callback to accept full row and use row.id instead of event_id for URL construction. Removed editableField rendering for media_uploads.
Event List Page Tests
src/pages/events/__tests__/summit-event-list-page.test.js
Comprehensive test suite (276 lines) validating afterUpdate prop behavior in bulk mode and media_uploads link navigation with and without event_id.
Event Material Page Tests
src/pages/events/__tests__/edit-event-material-page.test.js
New test suite (123 lines) verifying EditEventMaterialPage flows for regular and file-based material submission, including correct action invocations on mount.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • smarcet
  • romanetar
  • gcutrini

Poem

🐰 Hops of joy! The tests now bloom,
Events normalized, no more gloom!
Rows pass their secrets, render knows all,
Media uploads answer the call!
Speakers excluded, logic refined,
A cleaner design, beautifully aligned!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'fix: fix bulk inline edit mode for event activities' accurately describes the main changes: bulk update handling is refactored throughout the codebase, including EditableTable rendering, media_uploads workflow, and event normalization.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/fix-bulk-inline-edit-mode-event-activities

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/pages/events/summit-event-list-page.js (1)

1950-1963: ⚠️ Potential issue | 🟡 Minor

Add an inline comment explaining the intentional omission of afterUpdate in bulk edit mode.

The removal is intentional—a test explicitly verifies that afterUpdate is not passed in bulk mode. However, add a comment in the code (near the EditableTable component) explaining that afterUpdate is intentionally omitted to prevent bulk edits from triggering individual saveEventMaterial calls. This will clarify the design decision for future maintainers reviewing the code directly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/events/summit-event-list-page.js` around lines 1950 - 1963, Add an
inline comment next to the EditableTable JSX explaining that the absence of the
afterUpdate prop is intentional in bulk edit mode: mention that bulkUpdateEvents
is used instead and afterUpdate is omitted to avoid triggering per-row
saveEventMaterial calls (this omission is explicitly asserted in tests); locate
the comment near the EditableTable component props (EditableTable,
bulkUpdateEvents, afterUpdate, saveEventMaterial) so future maintainers
understand the design decision.
src/actions/event-actions.js (1)

510-540: ⚠️ Potential issue | 🟡 Minor

Speakers field in bulk edit requires clarification on intentional exclusion.

normalizeBulkEvents intentionally excludes speakers from the bulk update payload (per the test "does not include speakers in bulk payload"). However, for event types with use_speakers: true, the SpeakerInput component is rendered and editable in the bulk edit table (line 79 in summit-event-list-page.js). This creates a UX inconsistency: users can modify speakers in the UI for these event types, but the changes won't persist to the backend.

For event types where use_speakers: false, the speakers column is already hidden, so this is not an issue. But for event types that support speakers, consider either:

  • Disabling/hiding the speakers column in bulk edit mode, or
  • Adding speaker support to the bulk update payload if the backend supports it
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/actions/event-actions.js` around lines 510 - 540, normalizeBulkEvents
currently strips speakers from the bulk update payload causing a UX mismatch
when SpeakerInput is editable in bulk edit; fix by either (A) adding speakers
support to the bulk payload in normalizeBulkEvents: include a speakers property
(e.g., map e.speakers to an array of ids or objects the backend expects, using
existing helpers like getIdValue where appropriate) and ensure null/undefined
cleanup logic still applies, or (B) prevent editing by hiding/disabling the
SpeakerInput in the bulk edit UI (update summit-event-list-page.js to
conditionally render/disable SpeakerInput for bulk mode or for types with
use_speakers true but not editable in bulk); pick one approach and update tests
that assert "does not include speakers in bulk payload" to match the chosen
behavior.
🧹 Nitpick comments (1)
src/pages/events/__tests__/summit-event-list-page.test.js (1)

186-196: Fragile DOM traversal to access button click handler.

The nested props.children access pattern (lines 188-191) is brittle and will break if the render function's JSX structure changes. Consider extracting the render function and testing it in isolation, or using a more robust query approach.

// Alternative: Extract render function for direct testing
const mediaUploadsRender = mediaUploadsColumn.render;
// Then test the function directly with mock data
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/events/__tests__/summit-event-list-page.test.js` around lines 186 -
196, The test is using brittle DOM traversal to reach the click handler
(navigating nested props.children of mediaUploadsColumn.render output and
calling firstButton.props.onClick), so refactor the test to call
mediaUploadsColumn.render directly with a mock row (e.g., mediaUploadItem) and
inspect the returned element or query for the button more robustly;
specifically, extract mediaUploadsColumn.render into a variable
(mediaUploadsRender) and invoke it with the test data, then either find the
button by its component type/props within the returned React element or use a
DOM querying utility (React Testing Library) to locate the button and fire the
click, rather than assuming a specific children nesting structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/events/__tests__/edit-event-material-page.test.js`:
- Around line 13-16: The test's mocked EventMaterialForm currently submits only
{ id: 77 }, but saveEventMaterial derives the slug from entity.class_name (see
saveEventMaterial in src/actions/event-material-actions.js), so update the mock
submit payloads/regular-submit fixture to include a class_name (e.g., { id: 77,
class_name: "EventMaterial" }) so the test exercises the same routing logic as
runtime; make the same change for the other mocked submit used later in the file
to ensure both mocks include class_name.

---

Outside diff comments:
In `@src/actions/event-actions.js`:
- Around line 510-540: normalizeBulkEvents currently strips speakers from the
bulk update payload causing a UX mismatch when SpeakerInput is editable in bulk
edit; fix by either (A) adding speakers support to the bulk payload in
normalizeBulkEvents: include a speakers property (e.g., map e.speakers to an
array of ids or objects the backend expects, using existing helpers like
getIdValue where appropriate) and ensure null/undefined cleanup logic still
applies, or (B) prevent editing by hiding/disabling the SpeakerInput in the bulk
edit UI (update summit-event-list-page.js to conditionally render/disable
SpeakerInput for bulk mode or for types with use_speakers true but not editable
in bulk); pick one approach and update tests that assert "does not include
speakers in bulk payload" to match the chosen behavior.

In `@src/pages/events/summit-event-list-page.js`:
- Around line 1950-1963: Add an inline comment next to the EditableTable JSX
explaining that the absence of the afterUpdate prop is intentional in bulk edit
mode: mention that bulkUpdateEvents is used instead and afterUpdate is omitted
to avoid triggering per-row saveEventMaterial calls (this omission is explicitly
asserted in tests); locate the comment near the EditableTable component props
(EditableTable, bulkUpdateEvents, afterUpdate, saveEventMaterial) so future
maintainers understand the design decision.

---

Nitpick comments:
In `@src/pages/events/__tests__/summit-event-list-page.test.js`:
- Around line 186-196: The test is using brittle DOM traversal to reach the
click handler (navigating nested props.children of mediaUploadsColumn.render
output and calling firstButton.props.onClick), so refactor the test to call
mediaUploadsColumn.render directly with a mock row (e.g., mediaUploadItem) and
inspect the returned element or query for the button more robustly;
specifically, extract mediaUploadsColumn.render into a variable
(mediaUploadsRender) and invoke it with the test data, then either find the
button by its component type/props within the returned React element or use a
DOM querying utility (React Testing Library) to locate the button and fire the
click, rather than assuming a specific children nesting structure.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 297e8a7c-ba70-48b1-98a3-e427c8cb894b

📥 Commits

Reviewing files that changed from the base of the PR and between b29d23f and 9520b71.

📒 Files selected for processing (7)
  • src/actions/__tests__/event-actions-bulk.test.js
  • src/actions/event-actions.js
  • src/components/tables/editable-table/EditableTableRow.js
  • src/components/tables/editable-table/__tests__/EditableTable.test.js
  • src/pages/events/__tests__/edit-event-material-page.test.js
  • src/pages/events/__tests__/summit-event-list-page.test.js
  • src/pages/events/summit-event-list-page.js

Comment on lines +13 to +16
jest.mock("../../../components/forms/event-material-form", () => (props) => (
<div>
<button type="button" onClick={() => props.onSubmit({ id: 77 })}>
submit-material
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Include class_name in the regular-submit fixture.

Line 15 submits only { id: 77 }, but saveEventMaterial derives its slug from entity.class_name in src/actions/event-material-actions.js:71-86. That makes this test pass even if the page drops class_name and would hit the wrong "media-uploads" route at runtime.

Suggested change
 jest.mock("../../../components/forms/event-material-form", () => (props) => (
   <div>
-    <button type="button" onClick={() => props.onSubmit({ id: 77 })}>
+    <button
+      type="button"
+      onClick={() =>
+        props.onSubmit({ id: 77, class_name: "PresentationSlide" })
+      }
+    >
       submit-material
     </button>
@@
     expect(EventMaterialActions.saveEventMaterial).toHaveBeenCalledTimes(1);
     expect(EventMaterialActions.saveEventMaterial).toHaveBeenCalledWith({
-      id: 77
+      id: 77,
+      class_name: "PresentationSlide"
     });
   });

Also applies to: 90-92

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/events/__tests__/edit-event-material-page.test.js` around lines 13
- 16, The test's mocked EventMaterialForm currently submits only { id: 77 }, but
saveEventMaterial derives the slug from entity.class_name (see saveEventMaterial
in src/actions/event-material-actions.js), so update the mock submit
payloads/regular-submit fixture to include a class_name (e.g., { id: 77,
class_name: "EventMaterial" }) so the test exercises the same routing logic as
runtime; make the same change for the other mocked submit used later in the file
to ensure both mocks include class_name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant