Skip to content

Commit

Permalink
Merge branch 'v2.x/staging' of https://github.com/zowe/zen into revie…
Browse files Browse the repository at this point in the history
…wPage/tests
  • Loading branch information
sagaryadavs committed May 23, 2024
2 parents 78ad24a + 7fbf36b commit 2c82762
Show file tree
Hide file tree
Showing 19 changed files with 1,531 additions and 1,320 deletions.
57 changes: 35 additions & 22 deletions src/renderer/components/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import '../global.css';
import { useEffect, useState } from "react";
import { Link } from 'react-router-dom';
import { Box, Card, CardContent, CardMedia, Typography, Button, DialogContent, DialogActions } from '@mui/material';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import flatten, { unflatten } from 'flat';
import { IResponse, IIpcConnectionArgs } from '../../types/interfaces';
import { setConnectionArgs, selectConnectionArgs, selectInitJobStatement } from './stages/connection/connectionSlice';
import { setConnectionArgs, setResumeProgress, selectInitJobStatement } from './stages/connection/connectionSlice';
import { setJobStatement } from './stages/PlanningSlice';
import { setZoweCLIVersion } from './configuration-wizard/wizardSlice';
import { useAppDispatch, useAppSelector } from '../hooks';
Expand All @@ -28,6 +27,8 @@ import { selectConnectionStatus} from './stages/progress/progressSlice';
import HorizontalLinearStepper from './common/Stepper';
import Wizard from './configuration-wizard/Wizard'
import Connection from './stages/connection/Connection';
import { ActiveState } from '../../types/stateInterfaces';
import { getPreviousInstallation } from './stages/progress/StageProgressStatus';

// REVIEW: Get rid of routing

Expand Down Expand Up @@ -85,19 +86,28 @@ const makeCard = (card: ICard) => {
const Home = () => {

const dispatch = useAppDispatch();
const activeStepIndex = useAppSelector(selectActiveStepIndex);
const isSubStep = useAppSelector(selectIsSubstep);
const activeSubStepIndex = useAppSelector(selectActiveSubStepIndex);
const connectionStatus = useAppSelector(selectConnectionStatus);
const lastActiveDate = useAppSelector(selectActiveStepDate);
const initJobStatement = useAppSelector(selectInitJobStatement);

const [showWizard, setShowWizard] = useState(false);
const [showLoginDialog, setShowLogin] = useState(false);

const { activeStepIndex, isSubStep, activeSubStepIndex, lastActiveDate } = getPreviousInstallation();

const prevInstallationKey = "prev_installation";
const lastActiveState: ActiveState = {
activeStepIndex: 0,
isSubStep: false,
activeSubStepIndex: 0,
};
const [isNewInstallation, setIsNewInstallation] = useState(false);

const stages: any = [];
const defaultTooltip: string = "Resume";
const resumeTooltip = connectionStatus ? defaultTooltip : `Validate Credentials & ${defaultTooltip}`;

useEffect(() => {
eventDispatcher.on('saveAndCloseEvent', () => setShowWizard(false));


window.electron.ipcRenderer.checkZoweCLI().then((res: IResponse) => {
if (res.status) {
dispatch(setZoweCLIVersion(res.details));
Expand All @@ -121,6 +131,18 @@ const Home = () => {
// TODO: Add support for other types
console.warn('Connection types other than FTP are not supported yet');
}

const lastInstallation = localStorage.getItem(prevInstallationKey);
if (!lastInstallation) {
const flattenedData = flatten(lastActiveState);
localStorage.setItem(prevInstallationKey, JSON.stringify(flattenedData));
setIsNewInstallation(true);
} else {
const data: ActiveState = unflatten(JSON.parse(lastInstallation));
setIsNewInstallation(!(data && data.lastActiveDate));
}


});
return () => {
eventDispatcher.off('saveAndCloseEvent', () => setShowWizard(true));
Expand All @@ -129,33 +151,24 @@ const Home = () => {

const resumeProgress = () => {
setShowWizard(true);
setShowLogin(!connectionStatus);
eventDispatcher.emit('updateActiveStep', activeStepIndex, isSubStep, activeSubStepIndex);
dispatch(setResumeProgress(!connectionStatus));
}

return (
<>
<Dialog onClose={() => {}} open={showLoginDialog} style={{fontSize: '14px'}} fullWidth={true}
maxWidth={"lg"}>
<DialogTitle>Re-enter FTP Credentials</DialogTitle>
<Connection />
<DialogActions>
<Button onClick={() => setShowLogin(false)}>Close</Button>
</DialogActions>
</Dialog>
{!showWizard && <div className="home-container" style={{ display: 'flex', flexDirection: 'column' }}>

<div style={{ position: 'absolute', left: '-9999px' }}>
<HorizontalLinearStepper stages={stages} />
</div>

{!connectionStatus && <div style={{marginBottom: '50px'}}></div>}
{!connectionStatus && <div style={{marginBottom: '20px'}}></div>}

<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', marginLeft: '8%' }}>
{cards.map(card => makeCard(card))}
</div>

{connectionStatus && <div style={{marginBottom: '1px',marginTop: '120px',background: 'white', fontSize: 'small',marginLeft: 'calc(8% + 10px)', padding: '15px 0 15px 15px',width: 'calc(80% + 5px)', boxShadow: '1px 1px 3px #a6a6a6'}}>
{!isNewInstallation && <div style={{marginBottom: '1px',marginTop: '120px',background: 'white', fontSize: 'small',marginLeft: 'calc(8% + 10px)', padding: '15px 0 15px 15px',width: 'calc(80% + 5px)', boxShadow: '1px 1px 3px #a6a6a6'}}>
<Box sx={{display: 'flex', flexDirection: 'column'}}>

<div style={{paddingBottom: '10px', color: 'black'}}>
Expand All @@ -165,7 +178,7 @@ const Home = () => {
<Box sx={{display: 'flex', flexDirection: 'row', marginTop: '10px'}}>
<div style={{paddingRight: '10px'}}><span style={{color: 'black'}}>Last updated on:</span> {lastActiveDate}</div>
<div style={{marginBottom: '1px', marginTop: '-5px'}}>
<Tooltip title="Continue to Last Active Stage" arrow>
<Tooltip title={resumeTooltip} arrow>
<Button style={{ color: 'white', backgroundColor: '#1976d2', fontSize: '9px', padding: '4px'}} onClick={resumeProgress}>
Resume Progress
</Button>
Expand Down
37 changes: 21 additions & 16 deletions src/renderer/components/common/Stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ import eventDispatcher from '../../../utils/eventDispatcher';
import Warning from '@mui/icons-material/Warning';
import CheckCircle from '@mui/icons-material/CheckCircle';
import Home from '../Home';
import { getProgress, getCompleteProgress, mapAndSetSkipStatus, mapAndGetSkipStatus } from '../stages/progress/StageProgressStatus';

import '../../styles/Stepper.css';
import { StepIcon } from '@mui/material';
import { stages } from '../configuration-wizard/Wizard';
// TODO: define props, stages, stage interfaces
// TODO: One rule in the store to enable/disable button

Expand All @@ -43,21 +45,23 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages
const INIT_STAGE_ID = 3;
const REVIEW_STAGE_ID = 4;

const completeProgress = getCompleteProgress();

const stageProgressStatus = [
useSelector(selectConnectionStatus),
useSelector(selectPlanningStatus),
useSelector(selectInstallationTypeStatus),
useSelector(selectInitializationStatus),
useSelector(selectReviewStatus),
completeProgress.planningStatus,
completeProgress.installationTypeStatus,
completeProgress.initializationStatus,
completeProgress.reviewStatus
];

const subStageProgressStatus = [
useSelector(selectDatasetInstallationStatus),
useSelector(selectNetworkingStatus),
useSelector(selectApfAuthStatus),
useSelector(selectSecurityStatus),
useSelector(selectCertificateStatus),
useSelector(selectLaunchConfigStatus),
completeProgress.datasetInstallationStatus,
completeProgress.networkingStatus,
completeProgress.apfAuthStatus,
completeProgress.securityStatus,
completeProgress.certificateStatus,
completeProgress.launchConfigStatus
]

const TYPE_YAML = "yaml";
Expand Down Expand Up @@ -113,6 +117,7 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages
const handleSkip = () => {
stages[activeStep].isSkipped = true;
stages[activeStep].subStages[activeSubStep].isSkipped = true;
mapAndSetSkipStatus(activeSubStep, true);
handleNext();
}

Expand Down Expand Up @@ -165,18 +170,18 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages
setActiveStep(newActiveStep);
const newSubStep = isSubStep ? subStepIndex : 0;
setActiveSubStep(newSubStep);
};
}

const getStepIcon = (error: any, stageId: number, isSubStep?: boolean, subStepId?: number) => {

if ((error && activeStep>stageId && !isSubStep) || (error && isSubStep && stages[stageId].subStages[subStepId].isSkipped)) {
return <StepIcon icon={<Warning sx={{ color: 'orange', fontSize: '1.2rem' }} />} />;
}

if (!error) {
if (!error || (isSubStep && getProgress(stages[stageId].subStages[subStepId].statusKey)) || (!isSubStep && getProgress(stages[stageId].statusKey))) {
return <StepIcon icon={<CheckCircle sx={{ color: 'green', fontSize: '1.2rem' }} />} />;
}

if ((isSubStep && mapAndGetSkipStatus(subStepId)) || (error && activeStep>stageId && !isSubStep) || (error && isSubStep && stages[stageId].subStages[subStepId].isSkipped)) {
return <StepIcon icon={<Warning sx={{ color: 'orange', fontSize: '1.2rem' }} />} />;
}

else {
return (
<StepIcon
Expand Down
24 changes: 12 additions & 12 deletions src/renderer/components/configuration-wizard/Wizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ import Networking from '../stages/Networking';
import LaunchConfig from '../stages/LaunchConfig';

export const stages = [
{id: 0, label: 'Connection', component: <Connection/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: false, steps: 1, nextButton: 'Continue'},
{id: 1, label: 'Planning', component: <Planning/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: true, steps: 3, nextButton: 'Continue to Installation Options'},
{id: 2, label: 'Installation Type', component: <InstallationType/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: false, steps: 1, nextButton: 'Continue to Components Installation'},
{id: 0, label: 'Connection', component: <Connection/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: false, steps: 1, nextButton: 'Continue', statusKey: 'connectionStatus'},
{id: 1, label: 'Planning', component: <Planning/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: true, steps: 3, nextButton: 'Continue to Installation Options', statusKey: 'planningStatus'},
{id: 2, label: 'Installation Type', component: <InstallationType/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: false, steps: 1, nextButton: 'Continue to Components Installation', statusKey: 'installationTypeStatus'},
{id: 3, label: 'Initialization', component: <Initialization/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, subStages: [
{id: 0, label: 'Installation', component: <Installation/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Network Setup'},
{id: 1, label: 'Networking', component: <Networking/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to APF Auth Setup'},
{id: 2, label: 'APF Auth', component: <InitApfAuth/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Security Setup'},
{id: 3, label: 'Security', component: <Security/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Certificates Setup'},
{id: 4, label: 'Certificates', component: <Certificates/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Launch Setup'},
{id: 5, label: 'Launch Config', component: <LaunchConfig/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Instance Setup'},
], nextButton: 'Review'},
{id: 4, label: 'Review Installation', component: <ReviewInstallation/>, hasJCL: false, isSkippable: false, hasOutput: false, steps: 1, nextButton: 'Finish Installation'},
{id: 5, label: 'Finish Installation', component: <FinishInstallation/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: false, steps: 1},
{id: 0, label: 'Installation', component: <Installation/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Network Setup', statusKey: 'datasetInstallationStatus'},
{id: 1, label: 'Networking', component: <Networking/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to APF Auth Setup', statusKey: 'networkingStatus'},
{id: 2, label: 'APF Auth', component: <InitApfAuth/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Security Setup', statusKey: 'apfAuthStatus'},
{id: 3, label: 'Security', component: <Security/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Certificates Setup', statusKey: 'securityStatus'},
{id: 4, label: 'Certificates', component: <Certificates/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Launch Setup', statusKey: 'certificateStatus'},
{id: 5, label: 'Launch Config', component: <LaunchConfig/>, hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Instance Setup', statusKey: 'launchConfigStatus'},
], nextButton: 'Review', statusKey: 'initializationStatus'},
{id: 4, label: 'Review Installation', component: <ReviewInstallation/>, hasJCL: false, isSkippable: false, hasOutput: false, steps: 1, nextButton: 'Finish Installation', statusKey: 'reviewStatus'},
{id: 5, label: 'Finish Installation', component: <FinishInstallation/>, hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: false, steps: 1, statusKey: 'finishStatus'},
]

const Wizard = ({initialization}: {initialization: boolean}) => {
Expand Down
14 changes: 10 additions & 4 deletions src/renderer/components/stages/Certificates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { createTheme } from '@mui/material/styles';
import { stages } from "../configuration-wizard/Wizard";
import { setActiveStep } from "./progress/activeStepSlice";
import { getStageDetails, getSubStageDetails } from "../../../utils/StageDetails";
import { setProgress, getProgress, setCertificateInitState, getCertificateInitState } from "./progress/StageProgressStatus";
import { setProgress, getProgress, setCertificateInitState, getCertificateInitState, mapAndSetSkipStatus, getInstallationArguments } from "./progress/StageProgressStatus";
import { CertInitSubStepsState } from "../../../types/stateInterfaces";

const Certificates = () => {
Expand All @@ -44,7 +44,7 @@ const Certificates = () => {
const schema = useAppSelector(selectSchema);
const [yaml, setLYaml] = useState(useAppSelector(selectYaml));
const connectionArgs = useAppSelector(selectConnectionArgs);
const installationArgs = useAppSelector(selectInstallationArgs);
const installationArgs = getInstallationArguments();
const setupSchema = schema ? schema.properties.zowe.properties.setup.properties.certificate : "";
const verifyCertsSchema = schema ? {"type": "object", "properties": {"verifyCertificates": schema.properties.zowe.properties.verifyCertificates}} : "";
const [setupYaml, setSetupYaml] = useState(yaml?.zowe?.setup?.certificate);
Expand Down Expand Up @@ -154,10 +154,16 @@ const Certificates = () => {
}
}

const setStageSkipStatus = (status: boolean) => {
stages[STAGE_ID].subStages[SUB_STAGE_ID].isSkipped = status;
stages[STAGE_ID].isSkipped = status;
mapAndSetSkipStatus(SUB_STAGE_ID, status);
}

const updateProgress = (status: boolean) => {
setStateUpdated(!stateUpdated);
stages[STAGE_ID].subStages[SUB_STAGE_ID].isSkipped = !status;
stages[STAGE_ID].isSkipped = !status;
setStageSkipStatus(!status);

if(!status) {
for (let key in certificateInitProgress) {
certificateInitProgress[key as keyof(CertInitSubStepsState)] = false;
Expand Down
14 changes: 10 additions & 4 deletions src/renderer/components/stages/InitApfAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { createTheme } from '@mui/material/styles';
import { stages } from "../configuration-wizard/Wizard";
import { setActiveStep, selectActiveStepIndex, selectActiveSubStepIndex, selectIsSubstep } from "./progress/activeStepSlice";
import { getStageDetails, getSubStageDetails } from "../../../utils/StageDetails";
import { setProgress, getProgress, setApfAuthState, getApfAuthState } from "./progress/StageProgressStatus";
import { setProgress, getProgress, setApfAuthState, getApfAuthState, mapAndSetSkipStatus, getInstallationArguments } from "./progress/StageProgressStatus";
import { InitSubStepsState } from "../../../types/stateInterfaces";

const InitApfAuth = () => {
Expand Down Expand Up @@ -61,7 +61,7 @@ const InitApfAuth = () => {
const [initClicked, setInitClicked] = useState(false);
const [reinit, setReinit] = useState(false);

const installationArgs = useAppSelector(selectInstallationArgs);
const installationArgs = getInstallationArguments();
let timer: any;

const section = 'dataset';
Expand Down Expand Up @@ -148,10 +148,16 @@ const InitApfAuth = () => {
}
}

const setStageSkipStatus = (status: boolean) => {
stages[STAGE_ID].subStages[SUB_STAGE_ID].isSkipped = status;
stages[STAGE_ID].isSkipped = status;
mapAndSetSkipStatus(SUB_STAGE_ID, status);
}

const updateProgress = (status: boolean) => {
setStateUpdated(!stateUpdated);
stages[STAGE_ID].subStages[SUB_STAGE_ID].isSkipped = !status;
stages[STAGE_ID].isSkipped = !status;
setStageSkipStatus(!status);

if(!status) {
for (let key in apfAuthInitProgress) {
apfAuthInitProgress[key as keyof(InitSubStepsState)] = false;
Expand Down
2 changes: 0 additions & 2 deletions src/renderer/components/stages/Initialization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

import React, {useEffect} from "react";
import { useAppDispatch } from '../../hooks';
import Button from '@mui/material/Button';
import ProgressCard from '../common/ProgressCard';
import ContainerCard from '../common/ContainerCard';
import { setActiveStep } from "./progress/activeStepSlice";

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/stages/Networking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ const Networking = () => {
const theme = createTheme();

const stageLabel = 'Initialization';
const subStageLabel = 'APF Auth';
const subStageLabel = 'Networking';

const STAGE_ID = getStageDetails(stageLabel).id;
const SUB_STAGES = !!getStageDetails(stageLabel).subStages;
Expand Down
Loading

0 comments on commit 2c82762

Please sign in to comment.