From 5f18ca27a1cdc4ccb17a9ad3f113cf1c5ed1ca3d Mon Sep 17 00:00:00 2001 From: cproudlock Date: Tue, 4 Aug 2026 12:51:39 -0400 Subject: [PATCH] fix(installer): split the database page so every field is reachable Trimming the description brought the Username box back and left Password off the bottom. CreateInputQueryPage stacks its fields below the description and neither scrolls nor shrinks, so a field that does not fit is drawn past the surface and simply never appears - no error, no scrollbar. Sizing the description against a pixel budget that varies with DPI and font scaling is guesswork, and it had now failed twice. Connection details (host, port, database) and sign-in (username, password) are now two pages of three and two fields. Both fit under any reasonable description, at any scaling, without anyone having to estimate. The upgrade hint about leaving the password blank moves to the sign-in page, where the password field actually is. ShouldSkipPage hides both pages for the bundled-database option, and the stage arguments read the values from their new homes. --- deploy/windows/installer/ShopDBFlask.iss | 53 ++++++++++++++++++------ 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/deploy/windows/installer/ShopDBFlask.iss b/deploy/windows/installer/ShopDBFlask.iss index 13ae67d..cf147c7 100644 --- a/deploy/windows/installer/ShopDBFlask.iss +++ b/deploy/windows/installer/ShopDBFlask.iss @@ -181,6 +181,7 @@ Filename: "{win}\Sysnative\WindowsPowerShell\v1.0\powershell.exe"; \ var DbChoicePage: TInputOptionWizardPage; DbDetailsPage: TInputQueryWizardPage; + DbCredsPage: TInputQueryWizardPage; SitePage: TInputQueryWizardPage; PreflightPage: TWizardPage; BannerPanel: TPanel; @@ -414,17 +415,28 @@ begin DbDetailsPage.Add('Host:', False); DbDetailsPage.Add('Port:', False); DbDetailsPage.Add('Database:', False); - DbDetailsPage.Add('Username:', False); - DbDetailsPage.Add('Password:', True); DbDetailsPage.Values[0] := '127.0.0.1'; DbDetailsPage.Values[1] := '3306'; DbDetailsPage.Values[2] := 'shopdb_flask'; - DbDetailsPage.Values[3] := 'shopdb'; + + // SPLIT ACROSS TWO PAGES on purpose. CreateInputQueryPage stacks its fields + // below the description and does not scroll or shrink: with five fields the + // last one is drawn past the bottom of the surface and simply does not appear. + // Trimming the description bought one field back and lost the next, which is + // guessing at a pixel budget that varies with DPI and font. Three fields and + // two fields both fit under any reasonable description, at any scaling. + DbCredsPage := CreateInputQueryPage(DbDetailsPage.ID, + 'Existing database', 'Sign-in', + 'The account the application uses to reach that database. It needs full ' + + 'rights on it, and nothing outside it.'); + DbCredsPage.Add('Username:', False); + DbCredsPage.Add('Password:', True); + DbCredsPage.Values[0] := 'shopdb'; // How the application is published. Offered only when the bundle actually // carries a subpath SPA build - Vite compiles the base path in, so this can // never be a pure runtime switch. - DeployPage := CreateInputOptionPage(DbDetailsPage.ID, + DeployPage := CreateInputOptionPage(DbCredsPage.ID, 'Address', 'How should people reach ShopDB-Flask?', 'Both options serve the same application. The second needs no new DNS name ' + 'and no port number, because it rides this server''s existing address.', @@ -860,8 +872,20 @@ begin begin MsgBox('Enter the database host.', mbError, MB_OK); Result := False; + end; + end; + end; + + if CurPageID = DbCredsPage.ID then + begin + if not UseBundledDb then + begin + if DbCredsPage.Values[0] = '' then + begin + MsgBox('Enter the username the application connects with.', mbError, MB_OK); + Result := False; end - else if (DbDetailsPage.Values[4] = '') and + else if (DbCredsPage.Values[1] = '') and (not FileExists(InstalledDir + '.env')) then begin // Only required on a FRESH install. On an upgrade, blank means "keep the @@ -920,7 +944,7 @@ begin Creds := Copy(Existing, 1, Pos('@', Existing) - 1); Rest := Copy(Existing, Pos('@', Existing) + 1, Length(Existing)); if Pos(':', Creds) > 0 then - DbDetailsPage.Values[3] := Copy(Creds, 1, Pos(':', Creds) - 1); + DbCredsPage.Values[0] := Copy(Creds, 1, Pos(':', Creds) - 1); if Pos(':', Rest) > 0 then begin DbDetailsPage.Values[0] := Copy(Rest, 1, Pos(':', Rest) - 1); @@ -936,10 +960,13 @@ begin end; // Password intentionally left blank: blank means "keep the current // one", so an upgrade never needs the operator to know it. - DbDetailsPage.Values[4] := ''; + DbCredsPage.Values[1] := ''; DbDetailsPage.SubCaptionLabel.Caption := - 'These are the settings this server is using now. Leave the password ' - + 'blank to keep the current one.'; + 'These are the settings this server is using now.'; + // The hint belongs where the password field actually is - it moved to + // the next page when this one was split. + DbCredsPage.SubCaptionLabel.Caption := + 'Leave the password blank to keep the one this server already uses.'; end; end; @@ -990,7 +1017,7 @@ begin end; // The bundled path generates its own credentials, so asking for them would be // meaningless - and any value typed here would be silently ignored. - Result := (PageID = DbDetailsPage.ID) and UseBundledDb; + Result := ((PageID = DbDetailsPage.ID) or (PageID = DbCredsPage.ID)) and UseBundledDb; end; // Runs from ssPostInstall, NOT PrepareToInstall. @@ -1066,10 +1093,10 @@ begin // PowerShell transcripts. The installer shreds the file after reading it. // No password typed on an upgrade means "leave .env alone" - so send no // password file, and the installer keeps the existing DATABASE_URL. - if DbDetailsPage.Values[4] <> '' then + if DbCredsPage.Values[1] <> '' then begin PwFile := ExpandConstant('{tmp}\dbpw.txt'); - SaveStringToFile(PwFile, DbDetailsPage.Values[4] + #13#10, False); + SaveStringToFile(PwFile, DbCredsPage.Values[1] + #13#10, False); end else PwFile := ''; @@ -1077,7 +1104,7 @@ begin ' -DbHost "' + DbDetailsPage.Values[0] + '"' + ' -DbPort ' + DbDetailsPage.Values[1] + ' -DbName "' + DbDetailsPage.Values[2] + '"' + - ' -DbUser "' + DbDetailsPage.Values[3] + '"'; + ' -DbUser "' + DbCredsPage.Values[0] + '"'; if PwFile <> '' then Args := Args + ' -DbPasswordFile "' + PwFile + '"'; end;