Skip to content

Commit

Permalink
Merge pull request #92 from zowe/skip-action
Browse files Browse the repository at this point in the history
Skip action
  • Loading branch information
DivergentEuropeans committed Jan 8, 2024
2 parents 545d64e + 0ad400e commit 33ab5db
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 107 deletions.
8 changes: 4 additions & 4 deletions src/actions/InstallationHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,21 @@ class Installation {
}

public async initSecurity(connectionArgs: IIpcConnectionArgs,
installationArgs: {installationDir: string}, zoweConfig: any): Promise<any>{
installationArgs: {installationDir: string}, zoweConfig: any): Promise<IResponse>{
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('initSecurity.writeYaml', false);
ProgressStore.set('initSecurity.writeYaml', false);
return {status: false, details: `Can't save configuration to zowe.yaml`};
}
});
ProgressStore.set('initSecurity.writeYaml', true);
console.log("uploading yaml...");
const uploadYaml = await this.uploadYaml(connectionArgs, installationArgs.installationDir);
if(!uploadYaml.status){
return ProgressStore.set('initSecurity.uploadYaml', false);

return {status: false, details: `Error uploading yaml configuration: ${uploadYaml.details}`};
}
ProgressStore.set('initSecurity.uploadYaml', uploadYaml.status);
const script = `cd ${installationArgs.installationDir}/runtime/bin;\n./zwe init security -c ${installationArgs.installationDir}/zowe.yaml`;
Expand Down
16 changes: 11 additions & 5 deletions src/renderer/components/common/EditorDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ const EditorDialog = ({contentType, isEditorVisible, toggleEditorVisibility, onC
setZoweConfig(jsonData);
} else if(isSchemaValid && jsonData) {
setZoweConfig(jsonData);
dispatch(setNextStepEnabled(true));
setSetupYaml(jsonData);
updateConfig(jsonData);
}
Expand All @@ -119,7 +118,9 @@ const EditorDialog = ({contentType, isEditorVisible, toggleEditorVisibility, onC
properties.map(prop => {
setConfiguration(prop, setup[prop]);
});
onChange(setup, true);
if (onChange) {
onChange(setup, true);
}
}
}

Expand Down Expand Up @@ -174,9 +175,14 @@ const EditorDialog = ({contentType, isEditorVisible, toggleEditorVisibility, onC
<MonacoEditorComponent contentType={contentType} initialContent={editorContent} onContentChange={handleEditorContentChange} isSchemaValid={isSchemaValid} schemaError={schemaError} />
</DialogContent>
<DialogActions>
<Button onClick={triggerFileInputClick}>Import</Button>
<input type="file" ref={fileInputRef} style={{ display: 'none' }} onChange={handleFileUpload}/>
<Button onClick={handleFileExport}>Export</Button>
{contentType === 'yaml' && (
<>
<Button onClick={triggerFileInputClick}>Import</Button>
<input type="file" ref={fileInputRef} style={{ display: 'none' }} onChange={handleFileUpload} />
<Button onClick={handleFileExport}>Export</Button>
</>
)}
{contentType === 'jcl' && <Button onClick={toggleEditorVisibility}>Submit Job</Button>}
<Button onClick={toggleEditorVisibility}>Close</Button>
</DialogActions>
</Dialog>
Expand Down
82 changes: 73 additions & 9 deletions src/renderer/components/common/Stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,52 @@ import { selectConnectionStatus } from '../stages/connection/connectionSlice';
import { useAppSelector, useAppDispatch } from '../../hooks';
import { selectNextStepEnabled } from '../configuration-wizard/wizardSlice';
import { alertEmitter } from '../Header';
import EditorDialog from "./EditorDialog";
import { createTheme } from '@mui/material/styles';


// TODO: define props, stages, stage interfaces
// TODO: One rule in the store to enable/disable button

export default function HorizontalLinearStepper(props: any) {

const theme = createTheme();

const TYPE_YAML = "yaml";
const TYPE_JCL = "jcl";
const TYPE_OUTPUT = "output";

const {stages} = props;
const [activeStep, setActiveStep] = useState(0);
const [activeSubStep, setActiveSubStep] = useState(0);
const [skipped, setSkipped] = useState(new Set());
const [nextText, setNextText] = useState("Continue");
const [contentType, setContentType] = useState('output');
const [editorVisible, setEditorVisible] = useState(false);
const [editorContent, setEditorContent] = useState('');
const [currStep, setCurrStep] = useState(1);

const toggleEditorVisibility = (type?: any) => {
if (type) {
setContentType(type);
}
setEditorVisible(!editorVisible);
};

const getContinueText = () => {
return 'Continue to next step';//'+stages[activeStep+1].label;
};

const getSkipText = () => {
return 'Skip step';//+stages[activeStep+1].label;
};

const handleSubmit = () => {
//here:
// submit -> open editor with result -> mark skip button as continue button
stages[activeStep].successful = true;
toggleEditorVisibility(TYPE_OUTPUT);
};

const handleNext = () => {
alertEmitter.emit('hideAlert');
Expand All @@ -42,21 +78,31 @@ export default function HorizontalLinearStepper(props: any) {
return;
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setNextText(getContinueText());
}
};

const handleBack = () => {
alertEmitter.emit('hideAlert');
stages[activeStep].subStages && activeSubStep > 0 ? setActiveSubStep((prevActiveSubStep) => prevActiveSubStep - 1) : setActiveStep((prevActiveStep) => prevActiveStep - 1);
setNextText(getContinueText());
};

const handleReset = () => {
alertEmitter.emit('hideAlert');
setActiveStep(0);
};

const handlePreview = (test_jcl: any) => {
toggleEditorVisibility(TYPE_JCL);
setEditorContent(test_jcl);
};

const isNextStepEnabled = useAppSelector(selectNextStepEnabled);

return (
<Box className="stepper-container">
<EditorDialog contentType={contentType} isEditorVisible={editorVisible} toggleEditorVisibility={toggleEditorVisibility}/>
<Stepper className="stepper" activeStep={activeStep}>
{stages.map((stage: any, index: number) => {
const stepProps = {};
Expand Down Expand Up @@ -100,33 +146,51 @@ export default function HorizontalLinearStepper(props: any) {
<div style={{flexGrow: 1, display: 'flex', overflow: 'auto', height: stages[activeStep].subStages ? 'calc(100vh - 250px)' : 'calc(100vh - 200px)'}}>
{stages[activeStep].subStages ? stages[activeStep].subStages[activeSubStep].component : stages[activeStep].component}
</div>
<Box sx={{ display: 'flex', flexDirection: 'row', p: 2, borderTop: 'solid 1px lightgray' }}>
<Box sx={{ display: 'flex', flexDirection: 'row', p: 1, borderTop: 'solid 1px lightgray', justifyContent: 'flex-end'}}>
<Box sx={{ flex: '1 1 auto' }} >
{stages[activeStep].label === 'Planning' ? (
<Button variant="outlined" sx={{ marginRight: '3px', textTransform: 'none' }} onClick={() => handlePreview({})}>
Submit Job
</Button>
) : null}
</Box>
<Button
variant="outlined"
disabled={activeStep === 0}
onClick={handleBack}
sx={{ mr: 4 }}
>
Step back
sx={{ textTransform: 'none', mr: 1 }}>
Previous Step
</Button>
<Link style={{margin: 0}} to="/">
<Button // TODO: Not implemented
variant="text" sx={{ mr: 1 }}
variant="outlined"
sx={{ textTransform: 'none', mr: 1 }}
onClick={() => alertEmitter.emit('hideAlert')}>
Save and close
</Button>
</Link>
<Link style={{margin: 0}} to="/">
<Button
variant="text" sx={{ mr: 1 }}
variant="outlined"
sx={{ textTransform: 'none', mr: 1 }}
onClick={() => alertEmitter.emit('hideAlert')}>
Discard
Discard Setup
</Button>
</Link>
<Box sx={{ flex: '1 1 auto' }} />
{stages[activeStep].isSkippable &&
<Button
disabled={isNextStepEnabled}
variant="contained"
sx={{ textTransform: 'none', mr: 1 }}
onClick={() => handleNext()}
>
Skip {stages[activeStep].subStages ? stages[activeStep].subStages[activeSubStep].label : stages[activeStep].label}
</Button>
}
<Button
disabled={!useAppSelector(selectNextStepEnabled)}
disabled={!isNextStepEnabled}
variant="contained"
sx={{ textTransform: 'none', mr: 1 }}
onClick={() => handleNext()}
>
{stages[activeStep].subStages ? stages[activeStep].subStages[activeSubStep].nextButton : stages[activeStep].nextButton}
Expand Down
17 changes: 7 additions & 10 deletions src/renderer/components/configuration-wizard/Wizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,13 @@ import { selectLoading } from './wizardSlice';
import { useAppSelector } from '../../hooks';

const stages = [
{id: 0, label: 'Connection', component: <Connection/>, nextButton: 'Continue'},
{id: 1, label: 'Planning', component: <Planning/>, nextButton: 'Continue to installation options'},
{id: 2, label: 'Installation Type', component: <InstallationType/>, nextButton: 'Continue to components installation'},
// {id: 3, label: 'Installation', component: <Installation/>, nextButton: 'Continue to zowe Security'},
// {id: 4, label: 'Security', component: <Security/>, nextButton: 'Continue to certificates setup'},
// {id: 5, label: 'Certificates', component: <Certificates/>, nextButton: 'Continue to instance setup'},
{id: 6, label: 'Initialization', component: <Initialization/>, subStages: [
{id: 0, label: 'Installation', component: <Installation/>, nextButton: 'Continue to security setup'},
{id: 1, label: 'Security', component: <Security/>, nextButton: 'Continue to certificates setup'},
{id: 2, label: 'Certificates', component: <Certificates/>, nextButton: 'Continue to instance setup'},
{id: 0, label: 'Connection', component: <Connection/>, hasJCL: false, isSkippable: false, hasOutput: false, steps: 1, nextButton: 'Continue'},
{id: 1, label: 'Planning', component: <Planning/>, hasJCL: false, isSkippable: false, hasOutput: true, steps: 3, nextButton: 'Continue to Installation Options'},
{id: 2, label: 'Installation Type', component: <InstallationType/>, hasJCL: false, isSkippable: false, hasOutput: false, steps: 1, nextButton: 'Continue to Components Installation'},
{id: 3, label: 'Initialization', component: <Initialization/>, hasJCL: true, isSkippable: true, hasYaml: true, hasOutput: true, steps: 1, subStages: [
{id: 0, label: 'Installation', component: <Installation/>, hasJCL: true, isSkippable: true, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Security Setup'},
{id: 1, label: 'Security', component: <Security/>, hasJCL: true, isSkippable: true, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Certificates Setup'},
{id: 2, label: 'Certificates', component: <Certificates/>, hasJCL: true, isSkippable: true, hasYaml: true, hasOutput: true, steps: 1, nextButton: 'Continue to Instance Setup'},
], nextButton: <div style={{display: 'flex', alignItems: 'center'}}><img style={{width: '18px', height: '18px', paddingRight: '12px'}} src={spock}/>Live long and prosper</div>},
]

Expand Down
34 changes: 21 additions & 13 deletions src/renderer/components/stages/Certificates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,29 @@ import ContainerCard from '../common/ContainerCard';
import JsonForm from '../common/JsonForms';
import EditorDialog from "../common/EditorDialog";
import Ajv from "ajv";
import { createTheme } from '@mui/material/styles';

const Certificates = () => {

const theme = createTheme();

const dispatch = useAppDispatch();
const schema = useAppSelector(selectSchema);
const yaml = useAppSelector(selectYaml);
const setupSchema = schema ? schema.properties.zowe.properties.setup.properties.certificate : "";
const [setupYaml, setSetupYaml] = useState(yaml?.zowe.setup.certificate);
const [init, setInit] = useState(false);
const [isFormInit, setIsFormInit] = useState(false);
const [editorVisible, setEditorVisible] = useState(false);
const [isFormValid, setIsFormValid] = useState(false);
const [formError, setFormError] = useState('');
const [contentType, setContentType] = useState('');

const section = 'certificate';
const initConfig: any = getConfiguration(section);

const TYPE_YAML = "yaml";
const TYPE_JCL = "jcl";
const TYPE_OUTPUT = "output";

const ajv = new Ajv();
ajv.addKeyword("$anchor");
Expand All @@ -52,16 +58,17 @@ const Certificates = () => {
if(Object.keys(initConfig) && Object.keys(initConfig).length != 0) {
setSetupYaml(initConfig);
}
setInit(true);
setIsFormInit(true);
}, []);

const toggleEditorVisibility = () => {
const toggleEditorVisibility = (type: any) => {
setContentType(type);
setEditorVisible(!editorVisible);
};

const handleFormChange = (data: any, isYamlUpdated?: boolean) => {
let newData = init ? (Object.keys(initConfig).length > 0 ? initConfig: data) : (data ? data : initConfig);
setInit(false);
let newData = isFormInit ? (Object.keys(initConfig).length > 0 ? initConfig: data) : (data ? data : initConfig);
setIsFormInit(false);

if (newData) {
newData = isYamlUpdated ? data.certificate : newData;
Expand All @@ -88,29 +95,30 @@ const Certificates = () => {
if(validate.errors) {
const errPath = validate.errors[0].schemaPath;
const errMsg = validate.errors[0].message;
setStageConfig(false, errPath+' '+errMsg, newData, false);
setStageConfig(false, errPath+' '+errMsg, newData);
} else {
setConfiguration(section, newData, true);
setStageConfig(true, '', newData, true);
setStageConfig(true, '', newData);
}
}
}
};

const setStageConfig = (isValid: boolean, errorMsg: string, data: any, proceed: boolean) => {
const setStageConfig = (isValid: boolean, errorMsg: string, data: any) => {
setIsFormValid(isValid);
setFormError(errorMsg);
setSetupYaml(data);
dispatch(setNextStepEnabled(proceed));
}

return (
<div>
<div style={{ position: 'fixed', top: '190px', right: '30px'}}>
<Button style={{ color: 'white', backgroundColor: '#1976d2', fontSize: 'x-small'}} onClick={toggleEditorVisibility}>Open Editor</Button>
</div>
<Box sx={{ position:'absolute', bottom: '1px', display: 'flex', flexDirection: 'row', p: 1, justifyContent: 'flex-start', [theme.breakpoints.down('lg')]: {flexDirection: 'column',alignItems: 'flex-start'}}}>
<Button variant="outlined" sx={{ textTransform: 'none', mr: 1 }} onClick={() => toggleEditorVisibility(TYPE_YAML)}>View Yaml</Button>
<Button variant="outlined" sx={{ textTransform: 'none', mr: 1 }} onClick={() => toggleEditorVisibility(TYPE_JCL)}>Preview Job</Button>
<Button variant="outlined" sx={{ textTransform: 'none', mr: 1 }} onClick={() => toggleEditorVisibility(TYPE_OUTPUT)}>Submit Job</Button>
</Box>
<ContainerCard title="Certificates" description="Configure Zowe Certificates">
<EditorDialog contentType={TYPE_YAML} isEditorVisible={editorVisible} toggleEditorVisibility={toggleEditorVisibility} onChange={handleFormChange}/>
<EditorDialog contentType={contentType} isEditorVisible={editorVisible} toggleEditorVisibility={toggleEditorVisibility} onChange={handleFormChange}/>
<Box sx={{ width: '60vw' }}>
{!isFormValid && <div style={{color: 'red', fontSize: 'small', marginBottom: '20px'}}>{formError}</div>}
<JsonForm schema={setupSchema} onChange={handleFormChange} formData={setupYaml}/>
Expand Down
Loading

0 comments on commit 33ab5db

Please sign in to comment.