Страница зоны со всеми её устройствами и live-статусом

Раньше зона в списке была просто строкой без возможности провалиться
внутрь — все устройства смотрелись только через общий плоский список
/devices с колонкой "Зона". Теперь клик по зоне открывает её страницу
с карточками устройств (иконка по категории, статус online/offline/
unknown точкой с пульсацией для online, external_id) — ровно то, что
просили: все устройства и их статус на одном экране при выборе зоны.

Заодно список зон переведён с голой таблицы на карточки для
консистентности с новой страницей — вся карточка кликабельна и ведёт
на show, кнопки изменить/удалить остаются только у owner.

ZonePolicy::view уже был публичным (true всем) — новый роут
zones.show использует его без изменений.
This commit is contained in:
2026-08-13 13:07:01 +05:00
parent be1f238f89
commit f7aa0ba88e
8 changed files with 204 additions and 26 deletions
@@ -3,8 +3,10 @@
namespace App\Http\Controllers;
use App\Http\Requests\ZoneRequest;
use App\Http\Resources\DeviceResource;
use App\Http\Resources\ZoneResource;
use App\Models\Zone;
use App\Services\DeviceShadow;
use Inertia\Inertia;
class ZoneController extends Controller
@@ -20,6 +22,20 @@ class ZoneController extends Controller
]);
}
public function show(Zone $zone, DeviceShadow $shadow)
{
$this->authorize('view', $zone);
$devices = $zone->devices()->with('deviceType')->orderBy('name')->get();
$statuses = $shadow->statuses($devices->pluck('external_id')->all());
$devices->each(fn ($d) => $d->live_status = $statuses[$d->external_id] ?? 'unknown');
return Inertia::render('Zones/Show', [
'zone' => (new ZoneResource($zone))->resolve(),
'devices' => DeviceResource::collection($devices)->resolve(),
]);
}
public function create()
{
$this->authorize('create', Zone::class);