diff --git a/database/migrations/2026_05_19_120000_add_gmail_fields_to_support_approvals_table.php b/database/migrations/2026_05_19_120000_add_gmail_fields_to_support_approvals_table.php index f091bd77b..be15411aa 100644 --- a/database/migrations/2026_05_19_120000_add_gmail_fields_to_support_approvals_table.php +++ b/database/migrations/2026_05_19_120000_add_gmail_fields_to_support_approvals_table.php @@ -52,6 +52,15 @@ public function down(): void return; } + // SQLite refuses to drop a column while an index still references it. + foreach (['gmail_thread_id', 'gmail_message_id', 'notify_email'] as $column) { + if (Schema::hasColumn('support_approvals', $column)) { + Schema::table('support_approvals', function (Blueprint $table) use ($column) { + $table->dropIndex('support_approvals_'.$column.'_index'); + }); + } + } + Schema::table('support_approvals', function (Blueprint $table) { $columns = array_filter([ Schema::hasColumn('support_approvals', 'gmail_thread_id') ? 'gmail_thread_id' : null, diff --git a/database/migrations/2026_06_23_090000_add_cursor_agent_fields_to_support_cases_table.php b/database/migrations/2026_06_23_090000_add_cursor_agent_fields_to_support_cases_table.php index aef3af3e7..d6cbab4a6 100644 --- a/database/migrations/2026_06_23_090000_add_cursor_agent_fields_to_support_cases_table.php +++ b/database/migrations/2026_06_23_090000_add_cursor_agent_fields_to_support_cases_table.php @@ -25,6 +25,13 @@ public function up(): void public function down(): void { + // SQLite refuses to drop a column while an index still references it. + if (Schema::hasColumn('support_cases', 'cursor_agent_id')) { + Schema::table('support_cases', function (Blueprint $table) { + $table->dropIndex('support_cases_cursor_agent_id_index'); + }); + } + Schema::table('support_cases', function (Blueprint $table) { foreach (['cursor_agent_id', 'cursor_agent_status', 'cursor_pr_url', 'live_promotion_pr_url'] as $column) { if (Schema::hasColumn('support_cases', $column)) { diff --git a/resources/views/online-calendar/oc-index.blade.php b/resources/views/online-calendar/oc-index.blade.php index 308c5ab72..0bde1ba05 100644 --- a/resources/views/online-calendar/oc-index.blade.php +++ b/resources/views/online-calendar/oc-index.blade.php @@ -49,9 +49,15 @@ class="absolute top-0 right-0 h-full max-w-[calc(70vw)] object-cover hidden md:b + +@endsection +{{-- Rendered outside
on purpose. Vue mounts there with the runtime + compiler, which clears the container and rebuilds every node from the server HTML, + discarding Livewire's event listeners so the filters stop responding. --}} +@section('non-vue-content') +
@livewire('online-calendar') -
@endsection diff --git a/tests/Feature/OnlineEventsWorkflowTest.php b/tests/Feature/OnlineEventsWorkflowTest.php index d43fe3745..53c764c09 100644 --- a/tests/Feature/OnlineEventsWorkflowTest.php +++ b/tests/Feature/OnlineEventsWorkflowTest.php @@ -256,6 +256,28 @@ public function featured_activities_page_shows_all_upcoming_open_online_events() ->assertDontSee($pendingEvent->title); } + #[Test] + public function featured_activities_calendar_renders_outside_the_vue_root(): void + { + $this->seed('RolesAndPermissionsSeeder'); + + $html = $this->get('/featured-activities')->assertStatus(200)->getContent(); + + $nonVueStart = strpos($html, '
assertNotFalse($nonVueStart, 'Layout should expose the non-vue region.'); + $this->assertNotFalse($component, 'Calendar component should render.'); + + // Vue mounts on
with the runtime compiler, which clears the + // container and rebuilds every node, stripping Livewire's event listeners. + $this->assertGreaterThan( + $nonVueStart, + $component, + 'The calendar must render inside
, otherwise Vue destroys its Livewire bindings and the filters stop responding.' + ); + } + #[Test] public function featured_activities_month_filter_only_shows_events_for_selected_month(): void {