feat(setup): post-link redirects to SPA so first-setup matches live UI
CI / test (push) Has been cancelled
CI / test (push) Has been cancelled
Twig configure page replaced with a redirect: SetupController's index,
register, login, and the legacy /configure route all post-link redirect
to /?setup=<deviceId> for unconfigured devices. The SPA's HomeView
auto-opens its existing settings sheet for that id, with the same
controls everyone uses for live edits — themed to the user's choice,
pre-populated from the device record.
Fixes Matt's report:
- "every 6 hours" lost on save: the configure form posted
rotation_interval_hours but the controller read
rotation_interval_minutes, so the value silently defaulted to
1440 every time. Now the SPA's PATCH flow handles it correctly.
- "old settings still there in live settings": SPA settings sheet
pre-populates from the device's current state via onEdit.
- "uniqueness window in setup but not live settings": removed
from the (now-deleted) Twig form; both surfaces are consistent.
- "color scheme didn't match account": SPA respects the user's
theme natively (data-theme on <html>), so the first-setup screen
looks like the rest of the app.
Also adds a "Sign out of pictureFrame" link at the bottom of the
per-frame settings sheet (the existing /settings tab still has the
primary one). Easy escape hatch from a deeply-nested settings flow.
Tests:
- SetupControllerTest: S-03/04/05/06/08 updated for new redirect
targets, S-CLAIM-03 updated.
- HomeView.test.ts: useRoute now mockable per-test, two new cases
pinning the ?setup=<id> auto-open and its absence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,10 +39,7 @@ class SetupController extends AbstractController
|
||||
$user = $this->getUser();
|
||||
if (!$deviceService->isClaimedByAnotherUser($mac, $user)) {
|
||||
$device = $deviceService->linkToUser($mac, $user);
|
||||
if (empty($device->getName())) {
|
||||
return $this->redirectToRoute('setup_configure', ['mac' => $mac]);
|
||||
}
|
||||
return $this->redirectToRoute('spa');
|
||||
return $this->postLinkRedirect($device);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +91,7 @@ class SetupController extends AbstractController
|
||||
|
||||
$allowClaim = $request->request->getBoolean('claim_device');
|
||||
try {
|
||||
$deviceService->linkToUser($mac, $user, $allowClaim);
|
||||
$device = $deviceService->linkToUser($mac, $user, $allowClaim);
|
||||
} catch (DeviceClaimRequiredException) {
|
||||
// New account just created and claim wasn't acknowledged.
|
||||
// Bounce back through the setup page; the checkbox will be
|
||||
@@ -108,7 +105,7 @@ class SetupController extends AbstractController
|
||||
return $this->redirectToRoute('setup_index', ['mac' => $mac]);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('setup_configure', ['mac' => $mac]);
|
||||
return $this->postLinkRedirect($device);
|
||||
}
|
||||
|
||||
$existing = $em->getRepository(Device::class)->findOneBy(['mac' => strtoupper($mac)]);
|
||||
@@ -138,7 +135,7 @@ class SetupController extends AbstractController
|
||||
$security->login($user, 'form_login', 'main');
|
||||
$allowClaim = $request->request->getBoolean('claim_device');
|
||||
try {
|
||||
$deviceService->linkToUser($mac, $user, $allowClaim);
|
||||
$device = $deviceService->linkToUser($mac, $user, $allowClaim);
|
||||
} catch (DeviceClaimRequiredException) {
|
||||
$request->getSession()->set(
|
||||
'_setup_claim_error',
|
||||
@@ -146,50 +143,43 @@ class SetupController extends AbstractController
|
||||
);
|
||||
return $this->redirectToRoute('setup_index', ['mac' => $mac]);
|
||||
}
|
||||
return $this->redirectToRoute('setup_configure', ['mac' => $mac]);
|
||||
return $this->postLinkRedirect($device);
|
||||
}
|
||||
|
||||
$request->getSession()->set('_setup_login_error', 'Incorrect email or password');
|
||||
return $this->redirectToRoute('setup_index', ['mac' => $mac]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy route — first-time configuration now happens in the SPA's
|
||||
* settings sheet (auto-opens via the ?setup=<id> query param) so users
|
||||
* see the same controls as live editing, with their theme applied,
|
||||
* pre-populated from the device's current state. Kept as a redirect so
|
||||
* any in-flight bookmarks land in the right place.
|
||||
*/
|
||||
#[Route('/configure', name: 'setup_configure', methods: ['GET', 'POST'])]
|
||||
#[IsGranted('ROLE_USER')]
|
||||
public function configure(
|
||||
string $mac,
|
||||
Request $request,
|
||||
EntityManagerInterface $em,
|
||||
DeviceService $deviceService,
|
||||
): Response {
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
$device = $deviceService->linkToUser($mac, $user);
|
||||
return $this->postLinkRedirect($device);
|
||||
}
|
||||
|
||||
if ($request->isMethod('POST')) {
|
||||
$name = trim((string) $request->request->get('name', ''));
|
||||
$orient = $request->request->get('orientation', Orientation::Landscape->value);
|
||||
$interval = (int) $request->request->get('rotation_interval_minutes', 1440);
|
||||
$window = (int) $request->request->get('uniqueness_window', 10);
|
||||
|
||||
if (empty($name)) {
|
||||
return $this->render('setup/configure.html.twig', [
|
||||
'device' => $device,
|
||||
'error' => 'Please enter a name for your frame.',
|
||||
]);
|
||||
}
|
||||
|
||||
$device->setName($name);
|
||||
$device->setOrientation(Orientation::from($orient));
|
||||
$device->setRotationIntervalMinutes(max(1, $interval));
|
||||
$device->setUniquenessWindow(max(1, $window));
|
||||
$em->flush();
|
||||
|
||||
return $this->redirectToRoute('spa');
|
||||
/**
|
||||
* After linkToUser, hand off to the SPA. If the device hasn't been
|
||||
* named yet (= first-time setup), append ?setup=<id> so the SPA
|
||||
* auto-opens its settings sheet for that device. Avoids duplicating
|
||||
* the rich settings UI in a plain-Twig setup page.
|
||||
*/
|
||||
private function postLinkRedirect(Device $device): Response
|
||||
{
|
||||
if (empty($device->getName())) {
|
||||
return $this->redirect('/?setup=' . $device->getId());
|
||||
}
|
||||
|
||||
return $this->render('setup/configure.html.twig', [
|
||||
'device' => $device,
|
||||
'error' => null,
|
||||
]);
|
||||
return $this->redirectToRoute('spa');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user