From a8c747a088e9e53e3d18be7055f53de34c308854 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Mon, 20 May 2024 17:24:43 +0530 Subject: [PATCH 01/15] Updating the Wizard --- src/renderer/components/configuration-wizard/Wizard.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/renderer/components/configuration-wizard/Wizard.tsx b/src/renderer/components/configuration-wizard/Wizard.tsx index ec10c191..2d97de7a 100644 --- a/src/renderer/components/configuration-wizard/Wizard.tsx +++ b/src/renderer/components/configuration-wizard/Wizard.tsx @@ -23,6 +23,7 @@ import { selectLoading } from './wizardSlice'; import { useAppSelector } from '../../hooks'; import InitApfAuth from '../stages/InitApfAuth'; import Networking from '../stages/Networking'; +import Vsam from '../stages/Vsam'; import LaunchConfig from '../stages/LaunchConfig'; export const stages = [ @@ -34,8 +35,9 @@ export const stages = [ {id: 1, label: 'Networking', component: , 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: , hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Security Setup', statusKey: 'apfAuthStatus'}, {id: 3, label: 'Security', component: , hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Certificates Setup', statusKey: 'securityStatus'}, - {id: 4, label: 'Certificates', component: , 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: , hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Instance Setup', statusKey: 'launchConfigStatus'}, + {id: 4, label: 'Certificates', component: , hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Vsam Setup', statusKey: 'certificateStatus'}, + {id: 5, label: 'Vsam', component: , hasJCL: true, isSkippable: true, isSkipped: false, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Launch Setup', statusKey: 'vsamStatus'}, + {id: 6, label: 'Launch Config', component: , 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: , hasJCL: false, isSkippable: false, hasOutput: false, steps: 1, nextButton: 'Finish Installation', statusKey: 'reviewStatus'}, {id: 5, label: 'Finish Installation', component: , hasJCL: false, isSkippable: false, isSkipped: false, hasOutput: false, steps: 1, statusKey: 'finishStatus'}, From ea4dc3cd07b4ea153a9ad3f99bec46c69052ee4e Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Mon, 20 May 2024 17:28:02 +0530 Subject: [PATCH 02/15] Updating the interface file --- src/types/stateInterfaces.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/stateInterfaces.ts b/src/types/stateInterfaces.ts index 56a13a1f..fd6dccc5 100644 --- a/src/types/stateInterfaces.ts +++ b/src/types/stateInterfaces.ts @@ -18,6 +18,7 @@ export interface ProgressState { apfAuthStatus: boolean; securityStatus: boolean; certificateStatus: boolean; + vsamStatus: boolean; launchConfigStatus: boolean; reviewStatus: boolean; } From c9b0515a70ecaf981cee242fda22a8de99eb467d Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Mon, 20 May 2024 17:36:43 +0530 Subject: [PATCH 03/15] Updating the state functions --- .../stages/progress/StageProgressStatus.ts | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/renderer/components/stages/progress/StageProgressStatus.ts b/src/renderer/components/stages/progress/StageProgressStatus.ts index 66187e1f..fd9f29ac 100644 --- a/src/renderer/components/stages/progress/StageProgressStatus.ts +++ b/src/renderer/components/stages/progress/StageProgressStatus.ts @@ -28,6 +28,7 @@ const progressStatus: ProgressState = { apfAuthStatus: false, securityStatus: false, certificateStatus: false, + vsamStatus: false, launchConfigStatus: false, reviewStatus: false, } @@ -71,6 +72,12 @@ const certificateInitStatus: CertInitSubStepsState = { zweInitCertificate: false } +const vsamInitStatus: InitSubStepsState = { + writeYaml: false, + uploadYaml: false, + success: false +} + const planningValidationDetailsStatus: PlanningValidationDetails = { javaVersion: '', nodeVersion: '', @@ -84,6 +91,7 @@ const stepSkipStatus: SkipState = { apfAuth: false, security: false, certificate: false, + vsam: false, launchConfig: false } @@ -115,6 +123,7 @@ let datasetInstallationKey = 'dataset_installation'; let apfAuthKey = 'apf_auth'; let securityKey = 'security_init'; let certificateKey = 'certificate_init'; +let vsamKey = 'vsam_init'; let planningValidationDetailsKey = `planning_validation_details`; let prevInstallationKey = `prev_installation`; let skipStateKey = `skip_state`; @@ -131,6 +140,7 @@ const setKeys = (id: string) => { apfAuthKey = `${apfAuthKey}_${id}`; securityKey = `${securityKey}_${id}`; certificateKey = `${certificateKey}_${id}`; + vsamKey = `${vsamKey}_${id}`; planningValidationDetailsKey = `${planningValidationDetailsKey}_${id}`; skipStateKey = `${skipStateKey}_${id}`; installationArgsKey = `${installationArgsKey}_${id}`; @@ -188,6 +198,12 @@ export const initializeProgress = (host: string, user: string) => { localStorage.setItem(certificateKey, JSON.stringify(flattenedData)); } + const vsamInitState = localStorage.getItem(vsamKey); + if(!vsamInitState) { + const flattenedData = flatten(vsamInitStatus); + localStorage.setItem(vsamKey, JSON.stringify(flattenedData)); + } + const planningValidationDetailsState = localStorage.getItem(certificateKey); if(!planningValidationDetailsState) { const flattenedData = flatten(planningValidationDetailsStatus); @@ -219,6 +235,7 @@ export const mapAndGetSkipStatus = (subStageId: number): boolean => { skipStatus.apfAuth, skipStatus.security, skipStatus.certificate, + skipStatus.vsam, skipStatus.launchConfig ] @@ -307,6 +324,21 @@ export const getCertificateInitState = (): CertInitSubStepsState => { } } +export const setVsamInitStatus = (vsamInitSteps: InitSubStepsState): void => { + Object.assign(vsamInitStatus, vsamInitSteps); + localStorage.setItem(vsamKey, JSON.stringify(vsamInitStatus)); +} + +export const getVsamInitStatus = (): InitSubStepsState => { + const vsamInitState = localStorage.getItem(vsamKey); + if(vsamInitState) { + const flattenedData = JSON.parse(vsamInitState); + return unflatten(flattenedData) + } else { + return vsamInitStatus; + } +} + export const setDatasetInstallationState = (dsInstallSteps: DatasetInstallationState): void => { Object.assign(datasetInstallationStatus, dsInstallSteps); localStorage.setItem(datasetInstallationKey, JSON.stringify(datasetInstallationStatus)); From fc2c73d6fce3b4a930e55af19d1b61191d219e6a Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Mon, 20 May 2024 17:37:14 +0530 Subject: [PATCH 04/15] Updating the interfaces --- src/types/stateInterfaces.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/stateInterfaces.ts b/src/types/stateInterfaces.ts index fd6dccc5..87b0cc36 100644 --- a/src/types/stateInterfaces.ts +++ b/src/types/stateInterfaces.ts @@ -78,6 +78,7 @@ export interface SkipState { apfAuth: boolean, security: boolean, certificate: boolean, + vsam: boolean, launchConfig: boolean } From 1953480db0ce8a4a0fdb28391061d5a2084107c2 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Mon, 20 May 2024 17:46:30 +0530 Subject: [PATCH 05/15] updating the interfac eand state --- .../components/stages/progress/StageProgressStatus.ts | 4 ++-- src/renderer/components/stages/progress/progressSlice.ts | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/stages/progress/StageProgressStatus.ts b/src/renderer/components/stages/progress/StageProgressStatus.ts index fd9f29ac..73d31278 100644 --- a/src/renderer/components/stages/progress/StageProgressStatus.ts +++ b/src/renderer/components/stages/progress/StageProgressStatus.ts @@ -324,12 +324,12 @@ export const getCertificateInitState = (): CertInitSubStepsState => { } } -export const setVsamInitStatus = (vsamInitSteps: InitSubStepsState): void => { +export const setVsamInitState = (vsamInitSteps: InitSubStepsState): void => { Object.assign(vsamInitStatus, vsamInitSteps); localStorage.setItem(vsamKey, JSON.stringify(vsamInitStatus)); } -export const getVsamInitStatus = (): InitSubStepsState => { +export const getVsamInitState = (): InitSubStepsState => { const vsamInitState = localStorage.getItem(vsamKey); if(vsamInitState) { const flattenedData = JSON.parse(vsamInitState); diff --git a/src/renderer/components/stages/progress/progressSlice.ts b/src/renderer/components/stages/progress/progressSlice.ts index 9ffa4264..3ba8bf8d 100644 --- a/src/renderer/components/stages/progress/progressSlice.ts +++ b/src/renderer/components/stages/progress/progressSlice.ts @@ -23,6 +23,7 @@ const initialState: ProgressState = { apfAuthStatus: getProgress('apfAuthStatus') || false, securityStatus: getProgress('securityStatus') || false, certificateStatus: getProgress('certificateStatus') || false, + vsamStatus: getProgress('vsamStatus') || false, launchConfigStatus: getProgress('launchConfigStatus') || false, reviewStatus: getProgress('reviewStatus') || false } @@ -78,6 +79,10 @@ export const progressSlice = createSlice({ state.certificateStatus = action.payload; setProgress('certificateStatus', action.payload); }, + setVsamStatus: (state, action: PayloadAction) => { + state.vsamStatus = action.payload; + setProgress('vsamStatus', action.payload); + }, setLaunchConfigStatus: (state, action: PayloadAction) => { state.launchConfigStatus = action.payload; setProgress('launchConfigStatus', action.payload); @@ -89,7 +94,7 @@ export const progressSlice = createSlice({ } }); -export const { setConnectionStatus, setPlanningStatus, setInstallationTypeStatus, setInitializationStatus, setDatasetInstallationStatus, setNetworkingStatus, setApfAuthStatus, setSecurityStatus, setCertificateStatus, setLaunchConfigStatus, setReviewStatus } = progressSlice.actions; +export const { setConnectionStatus, setPlanningStatus, setInstallationTypeStatus, setInitializationStatus, setDatasetInstallationStatus, setNetworkingStatus, setApfAuthStatus, setSecurityStatus, setCertificateStatus, setVsamStatus, setLaunchConfigStatus, setReviewStatus } = progressSlice.actions; export const selectConnectionStatus = (state: RootState) => state.progress.connectionStatus; export const selectPlanningStatus = (state: RootState) => state.progress.planningStatus; @@ -100,6 +105,7 @@ export const selectNetworkingStatus= (state: RootState) => state.progress.networ export const selectApfAuthStatus = (state: RootState) => state.progress.apfAuthStatus; export const selectSecurityStatus = (state: RootState) => state.progress.securityStatus; export const selectCertificateStatus = (state: RootState) => state.progress.certificateStatus; +export const selectVsamStatus = (state: RootState) => state.progress.vsamStatus; export const selectLaunchConfigStatus = (state: RootState) => state.progress.launchConfigStatus; export const selectReviewStatus = (state: RootState) => state.progress.reviewStatus; From 055c19c1b8745f882c63d11b229a063e658105d3 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Mon, 20 May 2024 19:00:18 +0530 Subject: [PATCH 06/15] Init Vsam --- src/actions/InstallationHandler.ts | 22 ++ src/renderer/components/stages/Vsam.tsx | 254 ++++++++++++++++++++++++ 2 files changed, 276 insertions(+) create mode 100644 src/renderer/components/stages/Vsam.tsx diff --git a/src/actions/InstallationHandler.ts b/src/actions/InstallationHandler.ts index 0b8445f2..f5d2be0c 100644 --- a/src/actions/InstallationHandler.ts +++ b/src/actions/InstallationHandler.ts @@ -221,6 +221,28 @@ class Installation { return {status: result.rc === 0, details: result.jobOutput} } + async initVsam(connectionArgs: IIpcConnectionArgs, installationArgs: {installationDir: string, installationType: string}, zoweConfig: any){ + console.log('writing current yaml to disk'); + const filePath = path.join(app.getPath('temp'), 'zowe.yaml') + await fs.writeFile(filePath, stringify(zoweConfig), (err: any) => { + if (err) { + console.warn("Can't save configuration to zowe.yaml"); + return ProgressStore.set('vsam.writeYaml', false); + } + }); + ProgressStore.set('vsam.writeYaml', true); + console.log("uploading yaml..."); + const uploadYaml = await this.uploadYaml(connectionArgs, installationArgs.installationDir); + if(!uploadYaml.status){ + return ProgressStore.set('vsam.uploadYaml', false);; + } + ProgressStore.set('vsam.uploadYaml', uploadYaml.status); + const script = `cd ${installationArgs.installationType === "smpe" ? installationArgs.installationDir + '/bin' : installationArgs.installationDir + '/runtime/bin'} && ./zwe init vsam --update-config -c ${installationArgs.installationDir}/zowe.yaml`; + const result = await new Script().run(connectionArgs, script); + ProgressStore.set('vsam.success', result.rc === 0); + return {status: result.rc === 0, details: result.jobOutput} + } + async generateYamlFile(zoweConfig: object): Promise { const filePath = path.join(app.getPath('temp'), 'zowe.yaml') await fs.writeFile(filePath, stringify(zoweConfig), (err) => { diff --git a/src/renderer/components/stages/Vsam.tsx b/src/renderer/components/stages/Vsam.tsx new file mode 100644 index 00000000..b0f8e6d6 --- /dev/null +++ b/src/renderer/components/stages/Vsam.tsx @@ -0,0 +1,254 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ + +import { useState, useEffect } from "react"; +import { Box, Button, FormControl } from '@mui/material'; +import { useAppSelector, useAppDispatch } from '../../hooks'; +import { selectYaml, selectSchema, setNextStepEnabled, setYaml } from '../configuration-wizard/wizardSlice'; +import { setInitializationStatus, setVsamStatus } from './progress/progressSlice'; +import ContainerCard from '../common/ContainerCard'; +import JsonForm from '../common/JsonForms'; +import EditorDialog from "../common/EditorDialog"; +import Ajv from "ajv"; +import { selectConnectionArgs } from "./connection/connectionSlice"; +import { IResponse } from "../../../types/interfaces"; +import ProgressCard from "../common/ProgressCard"; +import React from "react"; +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, setVsamInitState, getSecurityInitState, mapAndSetSkipStatus, getInstallationArguments, getVsamInitState } from "./progress/StageProgressStatus"; +import { InitSubStepsState } from "../../../types/stateInterfaces"; + +const Security = () => { + + // TODO: Display granular details of installation - downloading - unpacking - running zwe command + + const stageLabel = 'Initialization'; + const subStageLabel = 'Vsam'; + + const STAGE_ID = getStageDetails(stageLabel).id; + const SUB_STAGES = !!getStageDetails(stageLabel).subStages; + const SUB_STAGE_ID = SUB_STAGES ? getSubStageDetails(STAGE_ID, subStageLabel).id : 0; + + const theme = createTheme(); + + const dispatch = useAppDispatch(); + const schema = useAppSelector(selectSchema); + const [yaml, setLYaml] = useState(useAppSelector(selectYaml)); + const setupSchema = schema?.properties?.zowe?.properties?.setup?.properties?.vsam; + const [setupYaml, setSetupYaml] = useState(yaml?.zowe?.setup?.vsam); + const [showProgress, setShowProgress] = useState(getProgress('vsamStatus')); + const [init, setInit] = useState(false); + const [editorVisible, setEditorVisible] = useState(false); + const [isFormValid, setIsFormValid] = useState(false); + const [formError, setFormError] = useState(''); + const [contentType, setContentType] = useState(''); + const [vsamInitProgress, setVsamInitProgress] = useState(getVsamInitState()); + const [stateUpdated, setStateUpdated] = useState(false); + const [initClicked, setInitClicked] = useState(false); + const [reinit, setReinit] = useState(false); + + const installationArgs = getInstallationArguments(); + const connectionArgs = useAppSelector(selectConnectionArgs); + let timer: any; + + const ajv = new Ajv(); + ajv.addKeyword("$anchor"); + let vsamSchema; + let validate: any; + if(schema) { + vsamSchema = schema?.properties?.zowe?.properties?.setup?.properties?.vsam; + } + + if(vsamSchema) { + validate = ajv.compile(vsamSchema); + } + + useEffect(() => { + + setShowProgress(initClicked || getProgress('vsamStatus')); + let nextPosition; + + if(getProgress('vsamStatus')) { + nextPosition = document.getElementById('vsam-progress'); + nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'end' }); + } else { + nextPosition = document.getElementById('container-box-id'); + nextPosition?.scrollIntoView({behavior: 'smooth'}); + } + + updateProgress(getProgress('vsamStatus')); + setInit(true); + + return () => { + dispatch(setActiveStep({ activeStepIndex: STAGE_ID, isSubStep: SUB_STAGES, activeSubStepIndex: SUB_STAGE_ID })); + } + }, []); + + useEffect(() => { + setShowProgress(initClicked || getProgress('vsamStatus')); + + if(initClicked) { + let nextPosition = document.getElementById('start-vsam-progress'); + nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'start' }); + setStateUpdated(!stateUpdated); + dispatch(setVsamStatus(false)); + } + }, [initClicked]); + + useEffect(() => { + if(!getProgress('vsamStatus') && initClicked) { + timer = setInterval(() => { + window.electron.ipcRenderer.getInitVsamProgress().then((res: any) => { + setVsamInitializationProgress(res); + }) + }, 3000); + + if(showProgress) { + console.log('vsam: if progress'); + const nextPosition = document.getElementById('start-vsam-progress'); + nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + } + return () => { + clearInterval(timer); + }; + }, [showProgress, stateUpdated]); + + useEffect(() => { + const allAttributesTrue = Object.values(vsamInitProgress).every(value => value === true); + if(allAttributesTrue) { + dispatch(setVsamStatus(true)); + dispatch(setNextStepEnabled(true)); + setShowProgress(initClicked || getProgress('vsamStatus')); + } + }, [vsamInitProgress]); + + const setVsamInitializationProgress = (vsamInitState: InitSubStepsState) => { + setVsamInitProgress(vsamInitState); + setVsamInitState(vsamInitState); + const allAttributesTrue = Object.values(vsamInitState).every(value => value === true); + if(allAttributesTrue) { + dispatch(setVsamStatus(true)); + dispatch(setNextStepEnabled(true)); + } + } + + 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); + setStageSkipStatus(!status); + if(!status) { + for (let key in vsamInitProgress) { + vsamInitProgress[key as keyof(InitSubStepsState)] = false; + setVsamInitState(vsamInitProgress); + } + } + const allAttributesTrue = Object.values(vsamInitProgress).every(value => value === true); + status = allAttributesTrue ? true : false; + dispatch(setInitializationStatus(status)); + dispatch(setVsamStatus(status)); + dispatch(setNextStepEnabled(status)); + setVsamInitializationProgress(getSecurityInitState()); + } + + const toggleEditorVisibility = (type: any) => { + setContentType(type); + setEditorVisible(!editorVisible); + }; + + const reinitialize = (event: any) => { + setReinit(true); + process(event); + } + + const process = (event: any) => { + setInitClicked(true); + updateProgress(false); + event.preventDefault(); + window.electron.ipcRenderer.initSecurityButtonOnClick(connectionArgs, installationArgs, yaml).then((res: IResponse) => { + updateProgress(res.status); + clearInterval(timer); + }).catch((error: any) => { + clearInterval(timer); + updateProgress(false); + console.warn('zwe init vsam failed'); + }); + } + + const handleFormChange = (data: any) => { + let newData = init ? (Object.keys(setupYaml).length > 0 ? setupYaml : data?.zowe?.setup?.vsam) : (data?.zowe?.setup?.vsam ? data?.zowe?.setup?.vsam : data); + setInit(false); + + if (newData) { + if(validate) { + validate(newData); + if(validate.errors) { + const errPath = validate.errors[0].schemaPath; + const errMsg = validate.errors[0].message; + setStageConfig(false, errPath+' '+errMsg, newData); + } else { + window.electron.ipcRenderer.setConfig({...yaml, zowe: {...yaml.zowe, setup: {...yaml.zowe.setup, vsam: newData}}}); + setStageConfig(true, '', newData); + } + } + } + }; + + const setStageConfig = (isValid: boolean, errorMsg: string, data: any) => { + setIsFormValid(isValid); + setFormError(errorMsg); + setSetupYaml(data); + } + + return ( +
+ + + + + + + {editorVisible && } + dispatch(setYaml((await window.electron.ipcRenderer.getConfig()).details.config ?? yaml))}> + {!isFormValid &&
{formError}
} + handleFormChange(data)} formData={setupYaml}/> + + {!showProgress ? + + : null} + + + + {!showProgress ? null : + + + + + + + } + +
+ + +
+
+ ); +}; + +export default Security; \ No newline at end of file From 56e33e47d70b5f8894ec354da377bc80656151e6 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Tue, 21 May 2024 14:09:09 +0530 Subject: [PATCH 07/15] final commit --- src/actions/InstallActions.ts | 5 ++ src/actions/InstallationHandler.ts | 48 +++++++++++-------- src/main/index.ts | 9 +++- .../components/stages/Certificates.tsx | 3 +- .../components/stages/InitApfAuth.tsx | 2 +- src/renderer/components/stages/Security.tsx | 4 +- src/renderer/components/stages/Vsam.tsx | 19 ++++---- src/renderer/preload.ts | 8 +++- 8 files changed, 60 insertions(+), 38 deletions(-) diff --git a/src/actions/InstallActions.ts b/src/actions/InstallActions.ts index 0501181b..fab0ed38 100644 --- a/src/actions/InstallActions.ts +++ b/src/actions/InstallActions.ts @@ -52,6 +52,11 @@ export class InstallActions { return this.strategy.initSecurity(connectionArgs, installationArgs, zoweConfig); } + initVsam(connectionArgs: IIpcConnectionArgs, + installationArgs: {installationDir: string, installationType: string}, zoweConfig: object): Promise { + return this.strategy.initVsam(connectionArgs, installationArgs, zoweConfig); + } + apfAuth(connectionArgs: IIpcConnectionArgs, installationArgs: {installationDir: string, installationType: string}, zoweConfig: object): Promise { return this.strategy.apfAuth(connectionArgs, installationArgs, zoweConfig); diff --git a/src/actions/InstallationHandler.ts b/src/actions/InstallationHandler.ts index f5d2be0c..4016426c 100644 --- a/src/actions/InstallationHandler.ts +++ b/src/actions/InstallationHandler.ts @@ -221,26 +221,34 @@ class Installation { return {status: result.rc === 0, details: result.jobOutput} } - async initVsam(connectionArgs: IIpcConnectionArgs, installationArgs: {installationDir: string, installationType: string}, zoweConfig: any){ - console.log('writing current yaml to disk'); - const filePath = path.join(app.getPath('temp'), 'zowe.yaml') - await fs.writeFile(filePath, stringify(zoweConfig), (err: any) => { - if (err) { - console.warn("Can't save configuration to zowe.yaml"); - return ProgressStore.set('vsam.writeYaml', false); - } - }); - ProgressStore.set('vsam.writeYaml', true); - console.log("uploading yaml..."); - const uploadYaml = await this.uploadYaml(connectionArgs, installationArgs.installationDir); - if(!uploadYaml.status){ - return ProgressStore.set('vsam.uploadYaml', false);; - } - ProgressStore.set('vsam.uploadYaml', uploadYaml.status); - const script = `cd ${installationArgs.installationType === "smpe" ? installationArgs.installationDir + '/bin' : installationArgs.installationDir + '/runtime/bin'} && ./zwe init vsam --update-config -c ${installationArgs.installationDir}/zowe.yaml`; - const result = await new Script().run(connectionArgs, script); - ProgressStore.set('vsam.success', result.rc === 0); - return {status: result.rc === 0, details: result.jobOutput} + public async initVsam(connectionArgs: IIpcConnectionArgs, + installationArgs: {installationDir: string, installationType: string}, zoweConfig: object): Promise{ + + // Initialize Progress Store For Vsam + ProgressStore.set('initVsam.writeYaml', false); + ProgressStore.set('initVsam.uploadYaml', false); + ProgressStore.set('initVsam.success', false); + + console.log('writing current yaml to disk'); + const filePath = path.join(app.getPath('temp'), 'zowe.yaml') + await fs.writeFile(filePath, stringify(zoweConfig), (err) => { + if (err) { + console.warn("Can't save configuration to zowe.yaml"); + ProgressStore.set('initVsam.writeYaml', false); + return {status: false, details: `Can't save configuration to zowe.yaml`}; + } + }); + ProgressStore.set('initVsam.writeYaml', true); + console.log("uploading yaml..."); + const uploadYaml = await this.uploadYaml(connectionArgs, installationArgs.installationDir); + if(!uploadYaml.status){ + return {status: false, details: `Error uploading yaml configuration: ${uploadYaml.details}`}; + } + ProgressStore.set('initVsam.uploadYaml', uploadYaml.status); + const script = `cd ${installationArgs.installationType === "smpe" ? installationArgs.installationDir + '/bin' : installationArgs.installationDir + '/runtime/bin'};./zwe init vsam -c ${installationArgs.installationDir}/zowe.yaml --allow-overwritten --update-config`; + const result = await new Script().run(connectionArgs, script); + ProgressStore.set('initVsam.success', result.rc === 0); + return {status: result.rc === 0, details: result.jobOutput} } async generateYamlFile(zoweConfig: object): Promise { diff --git a/src/main/index.ts b/src/main/index.ts index 9e76bfee..64d97b64 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -184,13 +184,20 @@ const createWindow = (): void => { return res; }); + ipcMain.handle('init-vsam', async (event, connectionArgs, installationArgs, zoweConfig) => { + const res = await installActions.initVsam(connectionArgs, installationArgs, zoweConfig); + return res; + }); ipcMain.handle('get-init-security-progress', async () => { const res = ProgressStore.getAll()['initSecurity']; return res; }); - + ipcMain.handle('get-init-vsam-progress', async () => { + const res = ProgressStore.getAll()['initVsam']; + return res; + }); const menuBuilder = new MenuBuilder(mainWindow); menuBuilder.buildMenu(); diff --git a/src/renderer/components/stages/Certificates.tsx b/src/renderer/components/stages/Certificates.tsx index c202b85c..9a4ed2bf 100644 --- a/src/renderer/components/stages/Certificates.tsx +++ b/src/renderer/components/stages/Certificates.tsx @@ -125,7 +125,6 @@ const Certificates = () => { } if(showProgress) { - console.log('security: if progress'); const nextPosition = document.getElementById('start-certificate-progress'); nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'start' }); } @@ -281,7 +280,7 @@ const Certificates = () => { } - + ); diff --git a/src/renderer/components/stages/InitApfAuth.tsx b/src/renderer/components/stages/InitApfAuth.tsx index 2c3e1b16..54ff66b3 100644 --- a/src/renderer/components/stages/InitApfAuth.tsx +++ b/src/renderer/components/stages/InitApfAuth.tsx @@ -292,7 +292,7 @@ const InitApfAuth = () => { } - + diff --git a/src/renderer/components/stages/Security.tsx b/src/renderer/components/stages/Security.tsx index b4f6e847..27e4cb73 100644 --- a/src/renderer/components/stages/Security.tsx +++ b/src/renderer/components/stages/Security.tsx @@ -89,7 +89,6 @@ const Security = () => { nextPosition?.scrollIntoView({behavior: 'smooth'}); } - updateProgress(getProgress('securityStatus')); setInit(true); @@ -118,7 +117,6 @@ const Security = () => { }, 3000); if(showProgress) { - console.log('security: if progress'); const nextPosition = document.getElementById('start-security-progress'); nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'start' }); } @@ -248,7 +246,7 @@ const Security = () => { } - + diff --git a/src/renderer/components/stages/Vsam.tsx b/src/renderer/components/stages/Vsam.tsx index b0f8e6d6..e9576e3f 100644 --- a/src/renderer/components/stages/Vsam.tsx +++ b/src/renderer/components/stages/Vsam.tsx @@ -25,10 +25,10 @@ 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, setVsamInitState, getSecurityInitState, mapAndSetSkipStatus, getInstallationArguments, getVsamInitState } from "./progress/StageProgressStatus"; +import { setProgress, getProgress, setVsamInitState, mapAndSetSkipStatus, getInstallationArguments, getVsamInitState } from "./progress/StageProgressStatus"; import { InitSubStepsState } from "../../../types/stateInterfaces"; -const Security = () => { +const Vsam = () => { // TODO: Display granular details of installation - downloading - unpacking - running zwe command @@ -114,7 +114,6 @@ const Security = () => { }, 3000); if(showProgress) { - console.log('vsam: if progress'); const nextPosition = document.getElementById('start-vsam-progress'); nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'start' }); } @@ -163,7 +162,7 @@ const Security = () => { dispatch(setInitializationStatus(status)); dispatch(setVsamStatus(status)); dispatch(setNextStepEnabled(status)); - setVsamInitializationProgress(getSecurityInitState()); + setVsamInitializationProgress(getVsamInitState()); } const toggleEditorVisibility = (type: any) => { @@ -180,7 +179,7 @@ const Security = () => { setInitClicked(true); updateProgress(false); event.preventDefault(); - window.electron.ipcRenderer.initSecurityButtonOnClick(connectionArgs, installationArgs, yaml).then((res: IResponse) => { + window.electron.ipcRenderer.initVsamButtonOnClick(connectionArgs, installationArgs, yaml).then((res: IResponse) => { updateProgress(res.status); clearInterval(timer); }).catch((error: any) => { @@ -222,14 +221,14 @@ const Security = () => { - + {editorVisible && } dispatch(setYaml((await window.electron.ipcRenderer.getConfig()).details.config ?? yaml))}> {!isFormValid &&
{formError}
} handleFormChange(data)} formData={setupYaml}/> {!showProgress ? - + : null} @@ -239,16 +238,16 @@ const Security = () => { - + }
- +
); }; -export default Security; \ No newline at end of file +export default Vsam; \ No newline at end of file diff --git a/src/renderer/preload.ts b/src/renderer/preload.ts index 5202db44..951e1d60 100644 --- a/src/renderer/preload.ts +++ b/src/renderer/preload.ts @@ -91,12 +91,18 @@ contextBridge.exposeInMainWorld('electron', { initSecurityButtonOnClick(connectionArgs: IIpcConnectionArgs, installationArgs: {installDir: string}, zoweConfig: any) { return ipcRenderer.invoke("init-security", connectionArgs, installationArgs, zoweConfig); }, + initVsamButtonOnClick(connectionArgs: IIpcConnectionArgs, installationArgs: {installDir: string}, zoweConfig: any) { + return ipcRenderer.invoke("init-vsam", connectionArgs, installationArgs, zoweConfig); + }, getInitSecurityProgress(){ return ipcRenderer.invoke("get-init-security-progress"); }, + getInitVsamProgress(){ + return ipcRenderer.invoke("get-init-vsam-progress"); + }, on(channel: string, func: any) { // REVIEW: Used to have channel validation with ipcRenderer.send, do we need something similar for ipcRenderer.invoke? - const validChannels = ['install-mvs', 'init-security']; + const validChannels = ['install-mvs', 'init-security', 'init-vsam']; if (validChannels.includes(channel)) { ipcRenderer.on(channel, (event, ...args) => func(...args)); } From b8d7dc717328e2bc54419f59a32a676f3b7e2c84 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Thu, 23 May 2024 14:36:40 +0530 Subject: [PATCH 08/15] Proper error handling --- src/actions/InstallationHandler.ts | 17 +++- .../configuration-wizard/wizardSlice.ts | 4 + src/renderer/components/stages/Vsam.tsx | 89 ++++++++++++++++--- src/types/interfaces.ts | 2 + 4 files changed, 99 insertions(+), 13 deletions(-) diff --git a/src/actions/InstallationHandler.ts b/src/actions/InstallationHandler.ts index 4016426c..18e451fd 100644 --- a/src/actions/InstallationHandler.ts +++ b/src/actions/InstallationHandler.ts @@ -247,8 +247,21 @@ class Installation { ProgressStore.set('initVsam.uploadYaml', uploadYaml.status); const script = `cd ${installationArgs.installationType === "smpe" ? installationArgs.installationDir + '/bin' : installationArgs.installationDir + '/runtime/bin'};./zwe init vsam -c ${installationArgs.installationDir}/zowe.yaml --allow-overwritten --update-config`; const result = await new Script().run(connectionArgs, script); - ProgressStore.set('initVsam.success', result.rc === 0); - return {status: result.rc === 0, details: result.jobOutput} + + let errorFound = false; + let errorMessage = ''; + const errorPattern = /Error ZWE.*/; + for (const key in result.jobOutput) { + const match = result.jobOutput[key].match(errorPattern); + if (match) { + errorFound = true; + errorMessage = match[0]; + break; + } + } + + ProgressStore.set('initVsam.success', result.rc === 0 && !errorFound); + return {status: result.rc === 0 && !errorFound, details: result.jobOutput, error: errorFound, errorMsg: errorMessage } } async generateYamlFile(zoweConfig: object): Promise { diff --git a/src/renderer/components/configuration-wizard/wizardSlice.ts b/src/renderer/components/configuration-wizard/wizardSlice.ts index c4af69b3..455c44da 100644 --- a/src/renderer/components/configuration-wizard/wizardSlice.ts +++ b/src/renderer/components/configuration-wizard/wizardSlice.ts @@ -10,6 +10,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { RootState } from '../../store'; +import { IResponse } from '../../../types/interfaces'; interface WizardState { loading: boolean; @@ -39,6 +40,9 @@ export const wizardSlice = createSlice({ }, setYaml: (state, action: PayloadAction) => { state.yaml = action.payload; + window.electron.ipcRenderer.setConfig(action.payload).then((res: IResponse) => { + // response + }); }, setSchema: (state, action: PayloadAction) => { state.schema = action.payload; diff --git a/src/renderer/components/stages/Vsam.tsx b/src/renderer/components/stages/Vsam.tsx index e9576e3f..e6e39508 100644 --- a/src/renderer/components/stages/Vsam.tsx +++ b/src/renderer/components/stages/Vsam.tsx @@ -9,7 +9,7 @@ */ import { useState, useEffect } from "react"; -import { Box, Button, FormControl } from '@mui/material'; +import { Box, Button, FormControl, TextField } from '@mui/material'; import { useAppSelector, useAppDispatch } from '../../hooks'; import { selectYaml, selectSchema, setNextStepEnabled, setYaml } from '../configuration-wizard/wizardSlice'; import { setInitializationStatus, setVsamStatus } from './progress/progressSlice'; @@ -27,6 +27,7 @@ import { setActiveStep } from "./progress/activeStepSlice"; import { getStageDetails, getSubStageDetails } from "../../../utils/StageDetails"; import { setProgress, getProgress, setVsamInitState, mapAndSetSkipStatus, getInstallationArguments, getVsamInitState } from "./progress/StageProgressStatus"; import { InitSubStepsState } from "../../../types/stateInterfaces"; +import { alertEmitter } from "../Header"; const Vsam = () => { @@ -57,10 +58,17 @@ const Vsam = () => { const [initClicked, setInitClicked] = useState(false); const [reinit, setReinit] = useState(false); + const [vsamDatasetName, setVsamDatasetName] = useState(""); + const [isDsNameValid, setIsDsNameValid] = useState(true); + const [initError, setInitError] = useState(false); + const [initErrorMsg, setInitErrorMsg] = useState(''); + const installationArgs = getInstallationArguments(); const connectionArgs = useAppSelector(selectConnectionArgs); let timer: any; + const defaultErrorMessage = "Please ensure that the volume, storage class & dataset values are accurate."; + const ajv = new Ajv(); ajv.addKeyword("$anchor"); let vsamSchema; @@ -90,6 +98,7 @@ const Vsam = () => { setInit(true); return () => { + alertEmitter.emit('hideAlert'); dispatch(setActiveStep({ activeStepIndex: STAGE_ID, isSubStep: SUB_STAGES, activeSubStepIndex: SUB_STAGE_ID })); } }, []); @@ -176,11 +185,18 @@ const Vsam = () => { } const process = (event: any) => { + alertEmitter.emit('hideAlert'); + setInitClicked(true); updateProgress(false); event.preventDefault(); window.electron.ipcRenderer.initVsamButtonOnClick(connectionArgs, installationArgs, yaml).then((res: IResponse) => { updateProgress(res.status); + if(res.error) { + setInitError(true); + setInitErrorMsg(`${res ? res.errorMsg : ''} ${defaultErrorMessage}`); + alertEmitter.emit('showAlert', res.errorMsg+" "+defaultErrorMessage, 'error'); + } clearInterval(timer); }).catch((error: any) => { clearInterval(timer); @@ -190,6 +206,8 @@ const Vsam = () => { } const handleFormChange = (data: any) => { + alertEmitter.emit('hideAlert'); + let newData = init ? (Object.keys(setupYaml).length > 0 ? setupYaml : data?.zowe?.setup?.vsam) : (data?.zowe?.setup?.vsam ? data?.zowe?.setup?.vsam : data); setInit(false); @@ -214,6 +232,36 @@ const Vsam = () => { setSetupYaml(data); } + const handleUpdateVsamName = (newName: string) => { + const updatedYaml = { + ...yaml, + components: { + ...yaml.components, + 'caching-service': { + ...yaml.components['caching-service'], + storage: { + ...yaml.components['caching-service'].storage, + vsam: { + ...yaml.components['caching-service'].storage.vsam, + name: newName + } + } + } + } + }; + setLYaml(updatedYaml); + dispatch(setYaml(updatedYaml)); + }; + + + const cachingServiceChangeHandler = (newValue: string) => { + alertEmitter.emit('hideAlert'); + const DsNamePattern = "^[a-zA-Z#$@][a-zA-Z0-9#$@-]{0,7}([.][a-zA-Z#$@][a-zA-Z0-9#$@-]{0,7}){0,21}$"; + const regEx = new RegExp(DsNamePattern); + setIsDsNameValid(regEx.test(newValue)); + handleUpdateVsamName(newValue); + } + return (
@@ -223,25 +271,44 @@ const Vsam = () => { {editorVisible && } + dispatch(setYaml((await window.electron.ipcRenderer.getConfig()).details.config ?? yaml))}> {!isFormValid &&
{formError}
} handleFormChange(data)} formData={setupYaml}/> + +
+ { + cachingServiceChangeHandler(e.target.value); + }} + /> + {isDsNameValid &&

Zowe Caching Service VSAM data set.

} + {!isDsNameValid &&

Invalid input. Please enter a valid VSAM dataset name.

} +
+
+ {!showProgress ? - + : null} - {!showProgress ? null : - - - - - - - } - + {!showProgress ? null : + + + + + + + } +
diff --git a/src/types/interfaces.ts b/src/types/interfaces.ts index 1f83c46a..e7eecbae 100644 --- a/src/types/interfaces.ts +++ b/src/types/interfaces.ts @@ -41,5 +41,7 @@ export interface IIpcConnectionArgs { export interface IResponse { status: boolean; details: any; + error?: boolean; + errorMsg?: string; } From 7ab06565b9132c079627e0f67f3bf87b2bbf032d Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Thu, 23 May 2024 14:57:48 +0530 Subject: [PATCH 09/15] datasetvalidation --- src/renderer/components/stages/Vsam.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/stages/Vsam.tsx b/src/renderer/components/stages/Vsam.tsx index e6e39508..54162c2e 100644 --- a/src/renderer/components/stages/Vsam.tsx +++ b/src/renderer/components/stages/Vsam.tsx @@ -86,6 +86,8 @@ const Vsam = () => { setShowProgress(initClicked || getProgress('vsamStatus')); let nextPosition; + datasetValidation(yaml?.components[`caching-service`]?.storage?.vsam?.name|| ''); + if(getProgress('vsamStatus')) { nextPosition = document.getElementById('vsam-progress'); nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'end' }); @@ -253,12 +255,16 @@ const Vsam = () => { dispatch(setYaml(updatedYaml)); }; + const datasetValidation = (dsName: string) => { + const DsNamePattern = "^[a-zA-Z#$@][a-zA-Z0-9#$@-]{0,7}([.][a-zA-Z#$@][a-zA-Z0-9#$@-]{0,7}){0,21}$"; + const regEx = new RegExp(DsNamePattern); + setIsDsNameValid(regEx.test(dsName)); + } + const cachingServiceChangeHandler = (newValue: string) => { alertEmitter.emit('hideAlert'); - const DsNamePattern = "^[a-zA-Z#$@][a-zA-Z0-9#$@-]{0,7}([.][a-zA-Z#$@][a-zA-Z0-9#$@-]{0,7}){0,21}$"; - const regEx = new RegExp(DsNamePattern); - setIsDsNameValid(regEx.test(newValue)); + datasetValidation(newValue); handleUpdateVsamName(newValue); } From 16c1bed61f967f116ec7b609cf3b65ffb2de19e3 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Thu, 23 May 2024 20:31:38 +0530 Subject: [PATCH 10/15] code removal --- src/renderer/components/stages/Planning.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/renderer/components/stages/Planning.tsx b/src/renderer/components/stages/Planning.tsx index 407113e7..f36de715 100644 --- a/src/renderer/components/stages/Planning.tsx +++ b/src/renderer/components/stages/Planning.tsx @@ -428,10 +428,12 @@ Please customize the job statement below to match your system requirements. {step > 0 - ? { dispatch(setYaml((await window.electron.ipcRenderer.getConfig()).details.config ?? localYaml)) }} onChange={(e) => { - dispatch(setYaml(localYaml)); - formChangeHandler(); - }} + ? + { dispatch(setYaml((await window.electron.ipcRenderer.getConfig()).details.config ?? localYaml)) }} onChange={(e) => { + // dispatch(setYaml(localYaml)); + // formChangeHandler(); + // }} > {`Now let's define some properties like z/OS Unix locations, identifiers, and z/OSMF details (optional).`} From f38d4d73d0f5beb2d001d6275a4f21815aef8a12 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Fri, 24 May 2024 12:18:46 +0530 Subject: [PATCH 11/15] Port as a number --- src/renderer/components/stages/Planning.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/renderer/components/stages/Planning.tsx b/src/renderer/components/stages/Planning.tsx index f36de715..9ada78c1 100644 --- a/src/renderer/components/stages/Planning.tsx +++ b/src/renderer/components/stages/Planning.tsx @@ -343,7 +343,7 @@ const Planning = () => { setStep(0); } - const formChangeHandler = (key?: string, value?: string, installationArg?: string) => { + const formChangeHandler = (key?: string, value?: any, installationArg?: string) => { setIsLocationsUpdated(true); setPlanningStatus(false); setLocationsValidated(false); @@ -429,12 +429,7 @@ Please customize the job statement below to match your system requirements. {step > 0 ? - { dispatch(setYaml((await window.electron.ipcRenderer.getConfig()).details.config ?? localYaml)) }} onChange={(e) => { - // dispatch(setYaml(localYaml)); - // formChangeHandler(); - // }} - > + {`Now let's define some properties like z/OS Unix locations, identifiers, and z/OSMF details (optional).`} @@ -684,7 +679,7 @@ Please customize the job statement below to match your system requirements. type="number" value={localYaml?.zOSMF?.port || installationArgs.zosmfPort} onChange={(e) => { - formChangeHandler("zOSMF.port", e.target.value, "zosmfPort"); + formChangeHandler("zOSMF.port", Number(e.target.value), "zosmfPort"); window.electron.ipcRenderer.setConfigByKey('zOSMF.port', Number(e.target.value)).then((res: any) => { // console.log('updated zowe.zOSMF.port') }) From e0860e2e8759a062b3fb485abf6a47d58f6d84c1 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Fri, 24 May 2024 13:53:28 +0530 Subject: [PATCH 12/15] no error at first for vsam ds --- src/renderer/components/stages/Vsam.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/renderer/components/stages/Vsam.tsx b/src/renderer/components/stages/Vsam.tsx index 54162c2e..21781be1 100644 --- a/src/renderer/components/stages/Vsam.tsx +++ b/src/renderer/components/stages/Vsam.tsx @@ -86,7 +86,10 @@ const Vsam = () => { setShowProgress(initClicked || getProgress('vsamStatus')); let nextPosition; - datasetValidation(yaml?.components[`caching-service`]?.storage?.vsam?.name|| ''); + const vsamDatasetName = yaml?.components[`caching-service`]?.storage?.vsam?.name|| ''; + if(vsamDatasetName) { + datasetValidation(vsamDatasetName); + } if(getProgress('vsamStatus')) { nextPosition = document.getElementById('vsam-progress'); From 5b7d7cbb0b1eda8a1e63d6d9e61402b660c842a9 Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Fri, 24 May 2024 14:40:52 +0530 Subject: [PATCH 13/15] Updating review installation --- src/renderer/components/stages/ReviewInstallation.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/components/stages/ReviewInstallation.tsx b/src/renderer/components/stages/ReviewInstallation.tsx index e28cf7a1..15550283 100644 --- a/src/renderer/components/stages/ReviewInstallation.tsx +++ b/src/renderer/components/stages/ReviewInstallation.tsx @@ -59,6 +59,7 @@ const ReviewInstallation = () => { completeProgress.apfAuthStatus, completeProgress.securityStatus, completeProgress.certificateStatus, + completeProgress.vsamStatus, completeProgress.launchConfigStatus ]; From 46b1e4564a4e8b866d85dfd7d2489c15b935e40d Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Fri, 24 May 2024 16:00:44 +0530 Subject: [PATCH 14/15] Bugfix --- src/renderer/components/stages/Vsam.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/renderer/components/stages/Vsam.tsx b/src/renderer/components/stages/Vsam.tsx index 21781be1..86a6b41a 100644 --- a/src/renderer/components/stages/Vsam.tsx +++ b/src/renderer/components/stages/Vsam.tsx @@ -235,6 +235,24 @@ const Vsam = () => { setIsFormValid(isValid); setFormError(errorMsg); setSetupYaml(data); + handleUpdateYaml(data); + } + + const handleUpdateYaml = (data: any) => { + const updatedYaml = { + ...yaml, + zowe: { + ...yaml.zowe, + setup: { + ...yaml.zowe.setup, + vsam: { + ...data, + } + } + } + }; + setLYaml(updatedYaml); + dispatch(setYaml(updatedYaml)); } const handleUpdateVsamName = (newName: string) => { From 3ec1da68836b749f0c7008e300341ffd722a39cd Mon Sep 17 00:00:00 2001 From: Sakshi Bobade Date: Fri, 24 May 2024 19:14:58 +0530 Subject: [PATCH 15/15] Final chages --- .../configuration-wizard/wizardSlice.ts | 2 +- src/renderer/components/stages/Vsam.tsx | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/renderer/components/configuration-wizard/wizardSlice.ts b/src/renderer/components/configuration-wizard/wizardSlice.ts index 455c44da..c73c254a 100644 --- a/src/renderer/components/configuration-wizard/wizardSlice.ts +++ b/src/renderer/components/configuration-wizard/wizardSlice.ts @@ -41,7 +41,7 @@ export const wizardSlice = createSlice({ setYaml: (state, action: PayloadAction) => { state.yaml = action.payload; window.electron.ipcRenderer.setConfig(action.payload).then((res: IResponse) => { - // response + // Response }); }, setSchema: (state, action: PayloadAction) => { diff --git a/src/renderer/components/stages/Vsam.tsx b/src/renderer/components/stages/Vsam.tsx index 86a6b41a..32c0bb67 100644 --- a/src/renderer/components/stages/Vsam.tsx +++ b/src/renderer/components/stages/Vsam.tsx @@ -222,29 +222,33 @@ const Vsam = () => { if(validate.errors) { const errPath = validate.errors[0].schemaPath; const errMsg = validate.errors[0].message; - setStageConfig(false, errPath+' '+errMsg, newData); + setStageConfig(false, errPath+' '+errMsg, newData, data); } else { window.electron.ipcRenderer.setConfig({...yaml, zowe: {...yaml.zowe, setup: {...yaml.zowe.setup, vsam: newData}}}); - setStageConfig(true, '', newData); + setStageConfig(true, '', newData, data); } } } }; - const setStageConfig = (isValid: boolean, errorMsg: string, data: any) => { + const setStageConfig = (isValid: boolean, errorMsg: string, data: any, updatedYaml?: any) => { setIsFormValid(isValid); setFormError(errorMsg); setSetupYaml(data); - handleUpdateYaml(data); + if(updatedYaml?.zowe) { + setLYaml(updatedYaml); + } + handleUpdateYaml(data, updatedYaml); } - const handleUpdateYaml = (data: any) => { + const handleUpdateYaml = (data: any, newYaml: any) => { + const currentYaml = newYaml?.zowe ? newYaml : yaml; const updatedYaml = { - ...yaml, + ...currentYaml, zowe: { - ...yaml.zowe, + ...currentYaml.zowe, setup: { - ...yaml.zowe.setup, + ...currentYaml.zowe.setup, vsam: { ...data, }