Skip to content

Commit

Permalink
Solving errors in merge to main (#59)
Browse files Browse the repository at this point in the history
* Disable login button if user don't want to share data (#49)

Signed-off-by: Montse Ortega <[email protected]>

* Add agent version to agent UI (#50)

Signed-off-by: Montse Ortega <[email protected]>

* Add agent version to Agent UI (#52)

Signed-off-by: Montse Ortega <[email protected]>

* ECOPROJECT-2357: Adjusting UI to last changes of API (#51)

* ECOPROJECT-2357: Adjusting UI to last changes of API

Signed-off-by: Montse Ortega <[email protected]>

* Use /url endpoint to get proper URL to UI (#53)

Signed-off-by: Ondra Machacek <[email protected]>

* Add .ova suffix to image (#54)

Signed-off-by: Ondra Machacek <[email protected]>

* Wait to load the sources table until agents and sources are loaded (#55)

Signed-off-by: Montse Ortega <[email protected]>

* Defining custom fotter for the wizard (#56)

Signed-off-by: Montse Ortega <[email protected]>

* Add example report PDF to be downloaded (#57)

Signed-off-by: Montse Ortega <[email protected]>

* Change Openshift text to OpenShift (#58)

Signed-off-by: Montse Ortega <[email protected]>

---------

Signed-off-by: Montse Ortega <[email protected]>
Signed-off-by: Ondra Machacek <[email protected]>
Co-authored-by: Ondra Machacek <[email protected]>
  • Loading branch information
ammont82 and machacekondra authored Dec 24, 2024
1 parent 20b797d commit 24847c0
Show file tree
Hide file tree
Showing 33 changed files with 907 additions and 287 deletions.
38 changes: 38 additions & 0 deletions apps/agent/src/common/AgentUIVersion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { useState, useEffect } from 'react';
import type { AgentApiInterface } from "@migration-planner-ui/agent-client/apis";
import { useInjection } from '@migration-planner-ui/ioc';
import { Symbols } from '#/main/Symbols';

export const AgentUIVersion: React.FC = () => {
const agentApi = useInjection<AgentApiInterface>(Symbols.AgentApi);
const [versionInfo, setVersionInfo] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const fetchVersion = async ():Promise<void> => {
try {
const statusReply = await agentApi.getAgentVersion();
setVersionInfo(statusReply);
} catch (err) {
console.error('Error fetching agent version:', err);
setError('Error fetching version');
}
};

fetchVersion();
}, [agentApi]);

if (error) {
return <div data-testid="agent-api-lib-version" hidden>Error: {error}</div>;
}

if (!versionInfo) {
return <div data-testid="agent-api-lib-version" hidden>Loading...</div>;
}

return (
<div data-testid="agent-api-lib-version" hidden>
{versionInfo}
</div>
);
};
4 changes: 3 additions & 1 deletion apps/agent/src/login-form/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ export const LoginForm: React.FC<LoginForm.Props> = (props) => {
name="isDataSharingAllowed"
label="I agree to share aggregated data about my environment with Red Hat."
aria-label="Share aggregated data"
onChange={(_event,checked)=>vm.handleChangeDataSharingAllowed(checked)}
isChecked={vm.isDataSharingChecked}
/>
</FormGroup>

Expand Down Expand Up @@ -236,7 +238,7 @@ export const LoginForm: React.FC<LoginForm.Props> = (props) => {
<Button
type="submit"
variant="primary"
isDisabled={vm.shouldDisableFormControl}
isDisabled={vm.shouldDisableFormControl || !vm.isDataSharingChecked}
form="login-form"
>
Log in
Expand Down
16 changes: 12 additions & 4 deletions apps/agent/src/login-form/hooks/UseViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export interface LoginFormViewModelInterface {
shouldDisplayAlert: boolean;
handleSubmit: React.FormEventHandler<HTMLFormElement>;
handleReturnToAssistedMigration: () => void;
handleChangeDataSharingAllowed: (checked:boolean)=>void;
isDataSharingChecked: boolean;
}

const _computeFormControlVariant = (
Expand All @@ -58,14 +60,15 @@ export const useViewModel = (): LoginFormViewModelInterface => {
);
const formRef = useRef<HTMLFormElement>();
const agentApi = useInjection<AgentApiInterface>(Symbols.AgentApi);
const [isDataSharingAllowed,setIsDataSharingAllowed] = useState<boolean>(DATA_SHARING_ALLOWED_DEFAULT_STATE);

useMount(() => {
const form = formRef.current;
if (!form) {
return;
}

form["isDataSharingAllowed"].checked = DATA_SHARING_ALLOWED_DEFAULT_STATE;
form["isDataSharingAllowed"].checked = isDataSharingAllowed;
});

useAsync(async () => {
Expand Down Expand Up @@ -222,9 +225,14 @@ export const useViewModel = (): LoginFormViewModelInterface => {
},
[agentApi, navigateTo]
),
handleReturnToAssistedMigration: useCallback(() => {
const assistedMigrationUrl = import.meta.env.ASSISTED_MIGRATION_URL || 'http://localhost:3000/migrate/wizard';
window.open(assistedMigrationUrl, '_blank', 'noopener,noreferrer');
handleReturnToAssistedMigration: useCallback(async () => {
const serviceUrl = await agentApi.getServiceUiUrl() || "http://localhost:3000/migrate/wizard";
window.open(serviceUrl, '_blank', 'noopener,noreferrer');
}, []),
handleChangeDataSharingAllowed: useCallback((checked)=>{
console.log(checked);
setIsDataSharingAllowed(checked);
},[]),
isDataSharingChecked: isDataSharingAllowed
};
};
2 changes: 2 additions & 0 deletions apps/agent/src/main/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from "@migration-planner-ui/ioc";
import { router } from "./Router";
import { Symbols } from "./Symbols";
import { AgentUIVersion } from "#/common/AgentUIVersion";

function getConfigurationBasePath(): string {
if (import.meta.env.PROD) {
Expand Down Expand Up @@ -40,6 +41,7 @@ function main(): void {
<React.StrictMode>
<DependencyInjectionProvider container={container}>
<React.Suspense fallback={<Spinner />}>
<AgentUIVersion />
<RouterProvider router={router} />
</React.Suspense>
</DependencyInjectionProvider>
Expand Down
Binary file added apps/demo/public/example_report.pdf
Binary file not shown.
24 changes: 24 additions & 0 deletions apps/demo/src/apis/MockAgentApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { AgentApiInterface, DeleteAgentRequest } from "@migration-planner-ui/api-client/apis";
import { Agent } from "@migration-planner-ui/api-client/models";
import { InitOverrideFunction, ApiResponse, ConfigurationParameters } from "@migration-planner-ui/api-client/runtime";

export class MockAgentApi implements AgentApiInterface {
constructor(_configuration: ConfigurationParameters) {
console.warn("#### CAUTION: Using MockAgentApi ####");
}

deleteAgentRaw(_requestParameters: DeleteAgentRequest, _initOverrides?: RequestInit | InitOverrideFunction): Promise<ApiResponse<Agent>> {
throw new Error("Method not implemented.");
}
deleteAgent(_requestParameters: DeleteAgentRequest, _initOverrides?: RequestInit | InitOverrideFunction): Promise<Agent> {
throw new Error("Method not implemented.");
}
listAgentsRaw(_initOverrides?: RequestInit | InitOverrideFunction): Promise<ApiResponse<Array<Agent>>> {
throw new Error("Method not implemented.");
}
async listAgents(_initOverrides?: RequestInit | InitOverrideFunction): Promise<Array<Agent>> {
const { default: json } = await import("./responses/agents.json");
return json as unknown as Array<Agent>;
}

}
19 changes: 3 additions & 16 deletions apps/demo/src/apis/MockSourceApi.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// import { sleep, Time } from "#/common/Time";
import {
CreateSourceRequest,
DeleteSourceRequest,
GetSourceImageRequest,
GetImageRequest,
ReadSourceRequest,
SourceApiInterface,
} from "@migration-planner-ui/api-client/apis";
Expand All @@ -18,18 +17,6 @@ export class MockSourceApi implements SourceApiInterface {
console.warn("#### CAUTION: Using MockSourceApi ####");
}

async createSourceRaw(
_requestParameters: CreateSourceRequest,
_initOverrides?: RequestInit | InitOverrideFunction
): Promise<ApiResponse<Source>> {
throw new Error("Method not implemented.");
}
async createSource(
_requestParameters: CreateSourceRequest,
_initOverrides?: RequestInit | InitOverrideFunction
): Promise<Source> {
throw new Error("Method not implemented.");
}
async deleteSourceRaw(
_requestParameters: DeleteSourceRequest,
_initOverrides?: RequestInit | InitOverrideFunction
Expand All @@ -53,13 +40,13 @@ export class MockSourceApi implements SourceApiInterface {
throw new Error("Method not implemented.");
}
async getSourceImageRaw(
_requestParameters: GetSourceImageRequest,
_requestParameters: GetImageRequest,
_initOverrides?: RequestInit | InitOverrideFunction
): Promise<ApiResponse<Blob>> {
throw new Error("Method not implemented.");
}
async getSourceImage(
_requestParameters: GetSourceImageRequest,
_requestParameters: GetImageRequest,
_initOverrides?: RequestInit | InitOverrideFunction
): Promise<Blob> {
throw new Error("Method not implemented.");
Expand Down
24 changes: 24 additions & 0 deletions apps/demo/src/apis/responses/agents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[
{
"associated": true,
"createdAt": "2024-12-11T07:22:40.264166+01:00",
"credentialUrl": "http://127.0.0.1:3333",
"sourceId": "29031FCA-3274-4067-A655-8BC4C322EA3F",
"id": "f8d28f7d-d862-47c5-b823-9763b319ff91",
"status": "up-to-date",
"statusInfo": "Inventory successfully collected",
"updatedAt": "2024-12-11T07:23:25.261977+01:00",
"version": "b1dc3f5"
},
{
"associated": true,
"createdAt": "2024-12-11T07:22:40.264166+01:00",
"credentialUrl": "http://127.0.0.1:3333",
"sourceId": "29031FCA-3274-4067-A655-8BC4C322EA3C",
"id": "f8d28f7d-d862-47c5-b823-9763b319ff92",
"status": "gathering-initial-inventory",
"statusInfo": "Gathering inventory",
"updatedAt": "2024-12-11T07:23:25.261977+01:00",
"version": "b1dc3f5"
}
]
6 changes: 5 additions & 1 deletion apps/demo/src/main/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider } from "react-router-dom";
import { Configuration } from "@migration-planner-ui/api-client/runtime";
import { SourceApi } from "@migration-planner-ui/api-client/apis";
import { AgentApi, SourceApi } from "@migration-planner-ui/api-client/apis";
import { Spinner } from "@patternfly/react-core";
import {
Container,
Expand All @@ -19,7 +19,11 @@ function getConfiguredContainer(): Container {
});
const container = new Container();
container.register(Symbols.SourceApi, new SourceApi(plannerApiConfig));
container.register(Symbols.AgentApi, new AgentApi(plannerApiConfig));

//For UI testing we can use the mock Apis
//container.register(Symbols.SourceApi, new MockSourceApi(plannerApiConfig));
//container.register(Symbols.AgentApi, new MockAgentApi(plannerApiConfig));
return container;
}

Expand Down
109 changes: 94 additions & 15 deletions apps/demo/src/migration-wizard/MigrationWizard.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,127 @@
import React from "react";
import { Wizard, WizardStep } from "@patternfly/react-core";
import {
Button,
useWizardContext,
Wizard,
WizardFooterWrapper,
WizardStep,
} from "@patternfly/react-core";
import { ConnectStep } from "./steps/connect/ConnectStep";
import { DiscoveryStep } from "./steps/discovery/DiscoveryStep";
import { useComputedHeightFromPageHeader } from "./hooks/UseComputedHeightFromPageHeader";
import { useDiscoverySources } from "./contexts/discovery-sources/Context";
import { PrepareMigrationStep } from "./steps/prepare-migration/PrepareMigrationStep";

const openAssistedInstaller = (): void => {
window.open("https://console.dev.redhat.com/openshift/assisted-installer/clusters/~new?source=assisted_migration", "_blank");
window.open(
"https://console.dev.redhat.com/openshift/assisted-installer/clusters/~new?source=assisted_migration",
"_blank"
);
};

type CustomWizardFooterPropType = {
isCancelHidden?: boolean;
isNextDisabled?: boolean;
isBackDisabled?: boolean;
nextButtonText?: string;
onNext?: () => void;
};

export const CustomWizardFooter: React.FC<CustomWizardFooterPropType> = ({
isCancelHidden,
isBackDisabled,
isNextDisabled,
nextButtonText,
onNext,
}): JSX.Element => {
const { goToNextStep, goToPrevStep, goToStepById } = useWizardContext();
return (
<>
<WizardFooterWrapper>
<Button
ouiaId="wizard-next-btn"
variant="primary"
onClick={() => {
if (onNext) {
onNext();
} else {
goToNextStep();
}
}}
isDisabled={isNextDisabled}
>
{nextButtonText ?? "Next"}
</Button>
<Button
ouiaId="wizard-back-btn"
variant="secondary"
onClick={goToPrevStep}
isDisabled={isBackDisabled}
>
Back
</Button>
{!isCancelHidden && (
<Button
ouiaId="wizard-cancel-btn"
variant="link"
onClick={() => goToStepById("connect-step")}
>
Cancel
</Button>
)}
</WizardFooterWrapper>
</>
);
};

export const MigrationWizard: React.FC = () => {
const computedHeight = useComputedHeightFromPageHeader();
const discoverSourcesContext = useDiscoverySources();
const isDiscoverySourceUpToDate = discoverSourcesContext.sourceSelected?.status === "up-to-date";

const isDiscoverySourceUpToDate =
discoverSourcesContext.agentSelected?.status === "up-to-date";

return (
<Wizard height={computedHeight}>
<WizardStep
name="Connect"
id="connect-step"
footer={{
isCancelHidden: true,
isNextDisabled: !isDiscoverySourceUpToDate,
}}
footer={
<CustomWizardFooter
isCancelHidden={true}
isNextDisabled={
!isDiscoverySourceUpToDate ||
discoverSourcesContext.sourceSelected === null
}
isBackDisabled={true}
/>
}
>
<ConnectStep />
</WizardStep>
<WizardStep
name="Discover"
id="discover-step"
footer={{ isCancelHidden: true }}
isDisabled={discoverSourcesContext.sourceSelected?.status !== 'up-to-date'}
footer={<CustomWizardFooter isCancelHidden={true} />}
isDisabled={
discoverSourcesContext.agentSelected?.status !== "up-to-date" ||
discoverSourcesContext.sourceSelected === null
}
>
<DiscoveryStep />
</WizardStep>
<WizardStep
name="Plan"
id="plan-step"
footer={{
nextButtonText: "Let's create a new cluster",
onNext: openAssistedInstaller,
}}
isDisabled={discoverSourcesContext.sourceSelected?.status !== 'up-to-date'}
footer={
<CustomWizardFooter
nextButtonText={"Let's create a new cluster"}
onNext={openAssistedInstaller}
/>
}
isDisabled={
discoverSourcesContext.agentSelected?.status !== "up-to-date" ||
discoverSourcesContext.sourceSelected === null
}
>
<PrepareMigrationStep />
</WizardStep>
Expand Down
Loading

0 comments on commit 24847c0

Please sign in to comment.