Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ const CreateVMWizardFooterComponent: React.FC<CreateVMWizardFooterComponentProps
);
};

const stateToProps = (state, { wizardReduxId }) => ({
stepData: iGetCreateVMWizardTabs(state, wizardReduxId),
const stateToProps = (state, { wizardReduxID }) => ({
stepData: iGetCreateVMWizardTabs(state, wizardReduxID),
});

export const CreateVMWizardFooter = connect(stateToProps)(CreateVMWizardFooterComponent);
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { isStepLocked, isStepValid } from './selectors/immutable/wizard-selector
import { VMSettingsTab } from './tabs/vm-settings-tab/vm-settings-tab';
import { ResourceLoadErrors } from './resource-load-errors';
import { CreateVMWizardFooter } from './create-vm-wizard-footer';
import { ReviewTab } from './tabs/review-tab/review-tab';

import './create-vm-wizard.scss';

Expand Down Expand Up @@ -157,7 +158,7 @@ export class CreateVMWizardComponent extends React.Component<CreateVMWizardCompo
// },
{
id: VMWizardTab.REVIEW,
component: <>VM review</>,
component: <ReviewTab wizardReduxID={reduxID} />,
},
{
id: VMWizardTab.RESULT,
Expand Down Expand Up @@ -207,7 +208,7 @@ export class CreateVMWizardComponent extends React.Component<CreateVMWizardCompo
});
return stepAcc;
}, [])}
footer={<CreateVMWizardFooter createVMText={createVMText} wizardReduxId={reduxID} />}
footer={<CreateVMWizardFooter createVMText={createVMText} wizardReduxID={reduxID} />}
/>
</div>
);
Expand Down Expand Up @@ -235,7 +236,7 @@ const wizardDispatchToProps = (dispatch, props) => ({
);
},
lockTab: (tabID) => {
dispatch(vmWizardActions[ActionType.SetTabLocked](props.reduxId, tabID, true));
dispatch(vmWizardActions[ActionType.SetTabLocked](props.reduxID, tabID, true));
},
onCommonDataChanged: (commonData: CommonData, changedCommonData: ChangedCommonData) => {
dispatch(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import "../../../../../../public/style/vars";

.kubevirt-form-field-form__container {
dt {
color: $color-text-muted;
text-transform: capitalize;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from 'react';
import { Form } from '@patternfly/react-core';
import { FormFieldReviewContext } from './form-field-review-context';

import './form-field-form.scss';

export const FormFieldForm: React.FC<FormFieldFormProps> = ({ children, isReview }) => {
const result = isReview ? (
<dl className="kubevirt-form-field-form__container">{children}</dl>
) : (
<Form>{children}</Form>
);
return (
<FormFieldReviewContext.Provider value={{ isReview }}>{result}</FormFieldReviewContext.Provider>
);
};
type FormFieldFormProps = {
children?: React.ReactNode;
isReview: boolean;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react';

export const FormFieldReviewContext = React.createContext({
isReview: false,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from 'react';
import { getFieldTitle } from '../utils/vm-settings-tab-utils';
import { iGetFieldValue } from '../selectors/immutable/vm-settings';
import { iGet } from '../../../utils/immutable';
import { getCheckboxReadableValue } from '../../../utils/strings';
import { FormFieldType } from './form-field';

type FormFieldReviewRowProps = {
field: any;
fieldType: FormFieldType;
};

export const FormFieldReviewRow: React.FC<FormFieldReviewRowProps> = ({ fieldType, field }) => {
const fieldKey = iGet(field, 'key');
const value = iGetFieldValue(field);
const reviewValue = [FormFieldType.CHECKBOX, FormFieldType.INLINE_CHECKBOX].includes(fieldType)
? getCheckboxReadableValue(value)
: value;
if (!reviewValue) {
return null;
}
return (
<>
<dt>{getFieldTitle(fieldKey)}</dt>
<dd>{reviewValue}</dd>
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as React from 'react';
import * as _ from 'lodash';
import { getFieldHelp, getFieldId, getFieldTitle } from '../utils/vm-settings-tab-utils';
import { isFieldHidden, isFieldRequired } from '../selectors/immutable/vm-settings';
import { iGetFieldValue, isFieldHidden, isFieldRequired } from '../selectors/immutable/vm-settings';
import { iGet, iGetIn, iGetIsLoaded } from '../../../utils/immutable';
import { FormRow } from '../../form/form-row';
import { FormFieldContext } from './form-field-context';
import { FormFieldType } from './form-field';
import { FormFieldReviewContext } from './form-field-review-context';
import { FormFieldReviewRow } from './form-field-review-row';

const isLoading = (loadingResources?: { [k: string]: any }) =>
loadingResources &&
Expand All @@ -26,19 +28,30 @@ export const FormFieldRow: React.FC<FieldFormRowProps> = ({
const loading = isLoading(loadingResources);

return (
<FormRow
fieldId={getFieldId(fieldKey)}
title={fieldType === FormFieldType.INLINE_CHECKBOX ? undefined : getFieldTitle(fieldKey)}
help={getFieldHelp(fieldKey, iGet(field, 'value'))}
isRequired={isFieldRequired(field)}
validationMessage={iGetIn(field, ['validation', 'message'])}
validationType={iGetIn(field, ['validation', 'type'])}
isLoading={loading}
>
<FormFieldContext.Provider value={{ field, fieldType, isLoading: loading }}>
{children}
</FormFieldContext.Provider>
</FormRow>
<FormFieldReviewContext.Consumer>
{({ isReview }: { isReview: boolean }) => {
if (isReview) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for better readability, I would implement these two branches as two components.

Copy link
Member Author

@atiratree atiratree Sep 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 I created FormFieldReviewRow component but left the other branch intact - because it is a single component and another wrapping layer would not help that much

return <FormFieldReviewRow field={field} fieldType={fieldType} />;
}
return (
<FormRow
fieldId={getFieldId(fieldKey)}
title={
fieldType === FormFieldType.INLINE_CHECKBOX ? undefined : getFieldTitle(fieldKey)
}
help={getFieldHelp(fieldKey, iGetFieldValue(field))}
isRequired={isFieldRequired(field)}
validationMessage={iGetIn(field, ['validation', 'message'])}
validationType={iGetIn(field, ['validation', 'type'])}
isLoading={loading}
>
<FormFieldContext.Provider value={{ field, fieldType, isLoading: loading }}>
{children}
</FormFieldContext.Provider>
</FormRow>
);
}}
</FormFieldReviewContext.Consumer>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';
import { VMSettingsTab } from '../vm-settings-tab/vm-settings-tab';

export const ReviewTab: React.FC<ReviewTabProps> = ({ wizardReduxID }) => {
return (
<>
<h3>Review and confirm your settings</h3>
<VMSettingsTab wizardReduxID={wizardReduxID} isReview />
</>
);
};

type ReviewTabProps = {
wizardReduxID: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,56 @@ import { isFieldHidden } from '../../selectors/immutable/vm-settings';
import './vm-settings-tab.scss';

export const MemoryCPU: React.FC<MemoryCPUProps> = React.memo(
({ memoryField, cpuField, onChange }) => {
({ memoryField, cpuField, onChange, isReview }) => {
if (isFieldHidden(memoryField) && isFieldHidden(cpuField)) {
return null;
}
const memory = (
<FormFieldMemoRow field={memoryField} fieldType={FormFieldType.TEXT}>
<FormField>
<Integer
className="kubevirt-create-vm-modal__memory-input"
isPositive
onChange={(value) => onChange(VMSettingsField.MEMORY, value)}
/>
</FormField>
</FormFieldMemoRow>
);

const cpu = (
<FormFieldMemoRow field={cpuField} fieldType={FormFieldType.TEXT}>
<FormField>
<Integer
className="kubevirt-create-vm-modal__cpu-input"
isPositive
onChange={(value) => onChange(VMSettingsField.CPU, value)}
/>
</FormField>
</FormFieldMemoRow>
);

if (isReview) {
return (
<>
{memory}
{cpu}
</>
);
}

return (
<Grid>
<GridItem span={6} className="kubevirt-create-vm-modal__memory-row">
<FormFieldMemoRow field={memoryField} fieldType={FormFieldType.TEXT}>
<FormField>
<Integer
className="kubevirt-create-vm-modal__memory-input"
isPositive
onChange={(value) => onChange(VMSettingsField.MEMORY, value)}
/>
</FormField>
</FormFieldMemoRow>
</GridItem>
<GridItem span={6}>
<FormFieldMemoRow field={cpuField} fieldType={FormFieldType.TEXT}>
<FormField>
<Integer
className="kubevirt-create-vm-modal__cpu-input"
isPositive
onChange={(value) => onChange(VMSettingsField.CPU, value)}
/>
</FormField>
</FormFieldMemoRow>
{memory}
</GridItem>
<GridItem span={6}>{cpu}</GridItem>
</Grid>
);
},
);

type MemoryCPUProps = {
isReview: boolean;
memoryField: any;
cpuField: any;
onChange: (key: string, value: string) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import {
Form,
FormSelect,
FormSelectOption,
TextArea,
Expand All @@ -18,6 +17,7 @@ import { iGetVmSettings } from '../../selectors/immutable/vm-settings';
import { ActionType } from '../../redux/types';
import { getFieldId, getPlaceholder } from '../../utils/vm-settings-tab-utils';
import { iGetCommonData } from '../../selectors/immutable/selectors';
import { FormFieldForm } from '../../form/form-field-form';
import { WorkloadProfile } from './workload-profile';
import { OSFlavor } from './os-flavor';
import { UserTemplates } from './user-templates';
Expand All @@ -35,17 +35,20 @@ export class VMSettingsTabComponent extends React.Component<VMSettingsTabCompone
onChange = (key) => (value) => this.props.onFieldChange(key, value);

render() {
const { userTemplates, commonTemplates, dataVolumes } = this.props;
const { userTemplates, commonTemplates, dataVolumes, isReview } = this.props;

return (
<Form>
<UserTemplates
userTemplateField={this.getField(VMSettingsField.USER_TEMPLATE)}
userTemplates={userTemplates}
commonTemplates={commonTemplates}
dataVolumes={dataVolumes}
onChange={this.props.onFieldChange}
/>
<FormFieldForm isReview={isReview}>
{!isReview && (
<UserTemplates
key={VMSettingsField.USER_TEMPLATE}
userTemplateField={this.getField(VMSettingsField.USER_TEMPLATE)}
userTemplates={userTemplates}
commonTemplates={commonTemplates}
dataVolumes={dataVolumes}
onChange={this.props.onFieldChange}
/>
)}
<FormFieldMemoRow
field={this.getField(VMSettingsField.PROVISION_SOURCE_TYPE)}
fieldType={FormFieldType.SELECT}
Expand Down Expand Up @@ -93,6 +96,7 @@ export class VMSettingsTabComponent extends React.Component<VMSettingsTabCompone
memoryField={this.getField(VMSettingsField.MEMORY)}
cpuField={this.getField(VMSettingsField.CPU)}
onChange={this.props.onFieldChange}
isReview={isReview}
/>
<WorkloadProfile
userTemplates={userTemplates}
Expand Down Expand Up @@ -134,7 +138,7 @@ export class VMSettingsTabComponent extends React.Component<VMSettingsTabCompone
/>
</FormField>
</FormFieldMemoRow>
</Form>
</FormFieldForm>
);
}
}
Expand All @@ -152,6 +156,7 @@ type VMSettingsTabComponentProps = {
commonTemplates: any;
userTemplates: any;
dataVolumes: any;
isReview: boolean;
};

const dispatchToProps = (dispatch, props) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,26 @@ const getDisksDescription = (
const description = [disk.name];

const volume = volumes.find((v) => v.name === disk.name);
if (volume.dataVolume) {
let dataVolume = dataVolumeTemplates.find((dv) => getName(dv) === volume.dataVolume.name);
if (!dataVolume) {
dataVolume = dataVolumes.find(
(dv) => getName(dv) === volume.dataVolume.name && getNamespace(dv) === getNamespace(vm),
if (volume) {
if (volume.dataVolume) {
let dataVolume = dataVolumeTemplates.find((dv) => getName(dv) === volume.dataVolume.name);
if (!dataVolume) {
dataVolume = dataVolumes.find(
(dv) => getName(dv) === volume.dataVolume.name && getNamespace(dv) === getNamespace(vm),
);
}
description.push(
getStorageSize(getDataVolumeResources(dataVolume)),
getDataVolumeStorageClassName(dataVolume),
);
} else if (volume.persistentVolumeClaim) {
const pvc = pvcs.find((p) => getName(p) === volume.persistentVolumeClaim.claimName);
description.push(getStorageSize(getPvcResources(pvc)), getPvcStorageClassName(pvc));
} else if (volume.containerDisk) {
description.push('container disk');
} else if (volume.cloudInitNoCloud) {
description.push('cloud-init disk');
}
description.push(
getStorageSize(getDataVolumeResources(dataVolume)),
getDataVolumeStorageClassName(dataVolume),
);
} else if (volume.persistentVolumeClaim) {
const pvc = pvcs.find((p) => getName(p) === volume.persistentVolumeClaim.claimName);
description.push(getStorageSize(getPvcResources(pvc)), getPvcStorageClassName(pvc));
} else if (volume.containerDisk) {
description.push('container disk');
} else if (volume.cloudInitNoCloud) {
description.push('cloud-init disk');
}
return <div key={disk.name}>{description.join(' - ')}</div>;
});
Expand Down
2 changes: 2 additions & 0 deletions frontend/packages/kubevirt-plugin/src/utils/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export const CREATED_WITH_FAILED_CLEANUP = 'created & failed to clean up';
export const CREATED_WITH_CLEANUP = 'created & cleaned up';
export const FAILED_TO_CREATE = 'failed to create';
export const FAILED_TO_PATCH = 'failed to patch';

export const getCheckboxReadableValue = (value: boolean) => (value ? 'yes' : 'no');