Skip to content

Commit 953fac8

Browse files
authored
Implement app config screen in the manager UI (#2435)
* Implement Config screen in the installer UI * fix ui * add unit test * fix lint errors
1 parent 6e20ed0 commit 953fac8

16 files changed

+2308
-1005
lines changed

web/package-lock.json

Lines changed: 1501 additions & 919 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
},
1414
"dependencies": {
1515
"@tailwindcss/forms": "^0.5.10",
16-
"@tailwindcss/postcss": "^4.1.11",
1716
"@tanstack/react-query": "^5.81.5",
1817
"lucide-react": "^0.525.0",
1918
"react": "^19.1.0",
@@ -23,7 +22,7 @@
2322
"devDependencies": {
2423
"@eslint/js": "^9.30.1",
2524
"@faker-js/faker": "^9.9.0",
26-
"@testing-library/jest-dom": "^6.6.3",
25+
"@testing-library/jest-dom": "^5.16.5",
2726
"@testing-library/react": "^16.3.0",
2827
"@testing-library/user-event": "^14.4.3",
2928
"@types/node": "^24.0.10",
@@ -38,10 +37,10 @@
3837
"jsdom": "^26.1.0",
3938
"msw": "2.10.3",
4039
"postcss": "^8.5.6",
41-
"tailwindcss": "^4.1.11",
40+
"tailwindcss": "^3.4.1",
4241
"typescript": "^5.8.3",
43-
"typescript-eslint": "^8.36.0",
44-
"vite": "^7.0.2",
42+
"typescript-eslint": "^8.35.1",
43+
"vite": "^6.3.5",
4544
"vite-plugin-static-copy": "^3.1.0",
4645
"vitest": "^3.2.4"
4746
}

web/postcss.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export default {
22
plugins: {
3-
'@tailwindcss/postcss': {},
3+
tailwindcss: {},
44
autoprefixer: {},
55
},
66
};

web/src/components/wizard/InstallWizard.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useState } from "react";
22
import StepNavigation from "./StepNavigation";
33
import WelcomeStep from "./WelcomeStep";
4+
import ConfigurationStep from "./config/ConfigurationStep";
45
import LinuxSetupStep from "./setup/LinuxSetupStep";
56
import KubernetesSetupStep from "./setup/KubernetesSetupStep";
67
import LinuxValidationStep from "./validation/LinuxValidationStep";
@@ -18,9 +19,9 @@ const InstallWizard: React.FC = () => {
1819

1920
const getSteps = (): WizardStep[] => {
2021
if (target === "kubernetes") {
21-
return ["welcome", "kubernetes-setup", "kubernetes-installation", "kubernetes-completion"];
22+
return ["welcome", "configuration", "kubernetes-setup", "kubernetes-installation", "kubernetes-completion"];
2223
} else {
23-
return ["welcome", "linux-setup", "linux-validation", "linux-installation", "linux-completion"];
24+
return ["welcome", "configuration", "linux-setup", "linux-validation", "linux-installation", "linux-completion"];
2425
}
2526
}
2627

@@ -44,10 +45,12 @@ const InstallWizard: React.FC = () => {
4445
switch (currentStep) {
4546
case "welcome":
4647
return <WelcomeStep onNext={goToNextStep} />;
48+
case "configuration":
49+
return <ConfigurationStep onNext={goToNextStep} />;
4750
case "linux-setup":
48-
return <LinuxSetupStep onNext={goToNextStep} />;
51+
return <LinuxSetupStep onNext={goToNextStep} onBack={goToPreviousStep} />;
4952
case "kubernetes-setup":
50-
return <KubernetesSetupStep onNext={goToNextStep} />;
53+
return <KubernetesSetupStep onNext={goToNextStep} onBack={goToPreviousStep} />;
5154
case "linux-validation":
5255
return <LinuxValidationStep onNext={goToNextStep} onBack={goToPreviousStep} />;
5356
case "linux-installation":

web/src/components/wizard/StepNavigation.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import { WizardStep } from '../../types';
3-
import { ClipboardList, Settings, Shield, Download, CheckCircle } from 'lucide-react';
3+
import { ClipboardList, Settings, Shield, Download, CheckCircle, Server } from 'lucide-react';
44
import { useWizard } from '../../contexts/WizardModeContext';
55
import { useSettings } from '../../contexts/SettingsContext';
66

@@ -25,13 +25,15 @@ const StepNavigation: React.FC<StepNavigationProps> = ({ currentStep: currentSte
2525
if (target === 'kubernetes') {
2626
return [
2727
{ id: 'welcome', name: 'Welcome', icon: ClipboardList },
28+
{ id: 'configuration', name: 'Configuration', icon: Server },
2829
{ id: 'kubernetes-setup', name: 'Setup', icon: Settings },
2930
{ id: 'kubernetes-installation', name: mode === 'upgrade' ? 'Upgrade' : 'Installation', icon: Download },
3031
{ id: 'kubernetes-completion', name: 'Completion', icon: CheckCircle },
3132
];
3233
} else {
3334
return [
3435
{ id: 'welcome', name: 'Welcome', icon: ClipboardList },
36+
{ id: 'configuration', name: 'Configuration', icon: Server },
3537
{ id: 'linux-setup', name: 'Setup', icon: Settings },
3638
{ id: 'linux-validation', name: 'Validation', icon: Shield, hidden: true, parentId: 'linux-setup' },
3739
{ id: 'linux-installation', name: mode === 'upgrade' ? 'Upgrade' : 'Installation', icon: Download },

web/src/components/wizard/WelcomeStep.tsx

Lines changed: 25 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Card from "../common/Card";
33
import Button from "../common/Button";
44
import Input from "../common/Input";
55
import { AppIcon } from "../common/Logo";
6-
import { ChevronRight, Lock, AlertTriangle } from "lucide-react";
6+
import { ChevronRight, Lock } from "lucide-react";
77
import { useWizard } from "../../contexts/WizardModeContext";
88
import { useMutation } from "@tanstack/react-query";
99
import { useAuth } from "../../contexts/AuthContext";
@@ -20,7 +20,6 @@ const WelcomeStep: React.FC<WelcomeStepProps> = ({ onNext }) => {
2020
const { text } = useWizard();
2121
const [password, setPassword] = useState("");
2222
const { setToken, isAuthenticated } = useAuth();
23-
const [showPasswordInput, setShowPasswordInput] = useState(true);
2423

2524
// Automatically redirect to SetupStep if already authenticated
2625
useEffect(() => {
@@ -60,11 +59,6 @@ const WelcomeStep: React.FC<WelcomeStepProps> = ({ onNext }) => {
6059
};
6160

6261
const handleSubmit = () => {
63-
if (!showPasswordInput) {
64-
setShowPasswordInput(true);
65-
return;
66-
}
67-
6862
if (!password.trim()) {
6963
return;
7064
}
@@ -73,7 +67,7 @@ const WelcomeStep: React.FC<WelcomeStepProps> = ({ onNext }) => {
7367
};
7468

7569
const handleKeyDown = (e: React.KeyboardEvent) => {
76-
if (e.key === "Enter" && showPasswordInput) {
70+
if (e.key === "Enter") {
7771
handleSubmit();
7872
}
7973
};
@@ -89,61 +83,29 @@ const WelcomeStep: React.FC<WelcomeStepProps> = ({ onNext }) => {
8983
<AppIcon className="h-20 w-20 mb-6" />
9084
<h2 className="text-3xl font-bold text-gray-900">{text.welcomeTitle}</h2>
9185
<p className="text-xl text-gray-600 max-w-2xl mb-8">{text.welcomeDescription}</p>
92-
{!showPasswordInput && (
93-
<>
94-
<div className="w-full max-w-2xl mb-8 p-4 bg-amber-50 border border-amber-200 rounded-lg">
95-
<div className="flex items-start">
96-
<div className="flex-shrink-0">
97-
<AlertTriangle className="h-5 w-5 text-amber-400" />
98-
</div>
99-
<div className="ml-3 text-left">
100-
<h3 className="text-sm font-medium text-amber-800">Self-Signed Certificate Warning</h3>
101-
<div className="mt-2 text-sm text-amber-700">
102-
<p>
103-
When you click "Continue", you'll be redirected to a secure HTTPS connection. Your browser will
104-
show a security warning because this wizard uses a self-signed certificate.
105-
</p>
106-
<p className="mt-2">To proceed:</p>
107-
<ol className="list-decimal list-inside mt-1 space-y-1">
108-
<li>Click "Advanced" or "Show Details" in your browser's warning</li>
109-
<li>Choose "Proceed" or "Continue" to the site</li>
110-
<li>You'll return to this page to enter your password</li>
111-
</ol>
112-
</div>
113-
</div>
114-
</div>
115-
</div>
116-
117-
<Button onClick={handleSubmit} size="lg" icon={<ChevronRight className="w-5 h-5" />} disabled={isLoading}>
118-
Continue Securely
119-
</Button>
120-
</>
121-
)}{" "}
122-
{showPasswordInput && (
123-
<div className="w-full max-w-sm mb-8">
124-
<Input
125-
id="password"
126-
label="Enter Password"
127-
type="password"
128-
value={password}
129-
onChange={handlePasswordChange}
130-
onKeyDown={handleKeyDown}
131-
error={loginError?.message}
132-
required
133-
icon={<Lock className="w-5 h-5" />}
134-
/>
135-
136-
<Button
137-
onClick={handleSubmit}
138-
size="lg"
139-
className="w-full mt-4"
140-
icon={<ChevronRight className="w-5 h-5" />}
141-
disabled={isLoading}
142-
>
143-
{text.welcomeButtonText}
144-
</Button>
145-
</div>
146-
)}
86+
<div className="w-full max-w-sm mb-8">
87+
<Input
88+
id="password"
89+
label="Enter Password"
90+
type="password"
91+
value={password}
92+
onChange={handlePasswordChange}
93+
onKeyDown={handleKeyDown}
94+
error={loginError?.message}
95+
required
96+
icon={<Lock className="w-5 h-5" />}
97+
/>
98+
99+
<Button
100+
onClick={handleSubmit}
101+
size="lg"
102+
className="w-full mt-4"
103+
icon={<ChevronRight className="w-5 h-5" />}
104+
disabled={isLoading}
105+
>
106+
{text.welcomeButtonText}
107+
</Button>
108+
</div>
147109
</div>
148110
</Card>
149111
</div>

0 commit comments

Comments
 (0)