Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<script>
/**
* Tenant-scoped Echo listener for Filament notifications
*
* WHY
* ----
* By default, Laravel/Filament subscribe to a user-only private channel:
* 'Eclipse.Core.Models.User.{id}'
*
* If the same user opens multiple tenants in different tabs,
* a broadcast to that channel will appear in all tabs.
*
* WHAT THIS FILE DOES
* -------------------
* - Subscribes instead to a tenant-aware channel:
* 'Eclipse.Core.Models.User.{uid}.tenant.{tid}'
*
* - Reads 'uid' and 'tid' from Filament's injected script data
* ('window.filamentData').
*
* - Re-emits incoming payloads as Filament's
* 'filament.notifications.received'
* event so the existing UI can render them.
*/
window.addEventListener('EchoLoaded', () => {
if (!window.Echo) return;

const { user, tenant } = window.filamentData ?? {};
const uid = user?.id;
const tid = tenant?.id;

if (!uid || !tid) return;

const channel = `Eclipse.Core.Models.User.${uid}.tenant.${tid}`;

window.Echo.private(channel).notification(payload => {
window.dispatchEvent(
new CustomEvent('filament.notifications.received', { detail: payload })
);
});
});
</script>


8 changes: 8 additions & 0 deletions src/EclipseServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
use Eclipse\Core\Providers\HorizonServiceProvider;
use Eclipse\Core\Providers\TelescopeServiceProvider;
use Eclipse\Core\Services\Registry;
use Filament\Facades\Filament;
use Filament\Resources\Resource;
use Filament\Support\Facades\FilamentAsset;
use Filament\Tables\Columns\Column;
use Illuminate\Auth\Events\Login;
use Illuminate\Database\Eloquent\Model;
Expand Down Expand Up @@ -148,6 +150,12 @@ public function boot(): void
->labels($availableLocales->pluck('native_name', 'id')->toArray());
});

// Register tenant and user IDs in Filament script data
FilamentAsset::registerScriptData([
'user' => ['id' => auth()->id()],
'tenant' => ['id' => Filament::getTenant()?->getKey()],
]);

// Register health checks
Health::checks([
OptimizedAppCheck::new(),
Expand Down
11 changes: 11 additions & 0 deletions src/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,15 @@ public function getSettings(string $settingsClass = UserSettings::class): Settin
{
return $settingsClass::forUser($this->id);
}

/**
* The channels the user receives notification broadcasts on.
*/
public function receivesBroadcastNotificationsOn(): string
{
$host = request()?->getHost();
$tenantId = Site::query()->where('domain', $host)->value('id');

return "Eclipse.Core.Models.User.{$this->id}.tenant.{$tenantId}";
}
}
1 change: 1 addition & 0 deletions src/Providers/AdminPanelProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ public function register(): void
parent::register();

FilamentView::registerRenderHook('panels::body.end', fn (): string => Blade::render("@vite('resources/js/app.js')"));
FilamentView::registerRenderHook('panels::body.end', fn (): string => view('eclipse::filament.partials.tenant-scoped-notifications')->render());
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Services/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static function setSite(int|Site $site): void

Context::add('site', self::getSite()->id);

setPermissionsTeamId($site->id);
setPermissionsTeamId(self::getSite()->id);
}

/**
Expand Down