Skip to content

Commit

Permalink
Add yaml editor for values.yaml in helm install form
Browse files Browse the repository at this point in the history
  • Loading branch information
rohitkrai03 committed Feb 26, 2020
1 parent 883c693 commit 9261dd1
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.yaml-editor-formik-field {
margin: 0 !important;
padding: 0 !important;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react';
import { FormikValues, useField, useFormikContext } from 'formik';
import { FormGroup } from '@patternfly/react-core';
import { YAMLEditorFieldProps } from './field-types';
import { getFieldId } from './field-utils';
import { AsyncComponent } from '@console/internal/components/utils';
import './YAMLEditorField.scss';

const YAMLEditorField: React.FC<YAMLEditorFieldProps> = ({ name }) => {
const [field] = useField(name);
const { setFieldValue } = useFormikContext<FormikValues>();
const fieldId = getFieldId(name, 'yaml-editor');

return (
<FormGroup fieldId={fieldId}>
<AsyncComponent
loader={() => import('@console/internal/components/edit-yaml').then((c) => c.EditYAML)}
obj={field.value}
onChange={(yaml: string) => setFieldValue(name, yaml)}
download={false}
customClass="yaml-editor-formik-field"
create
hideHeader
genericYAML
hideActions
/>
</FormGroup>
);
};

export default YAMLEditorField;
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export interface MultiColumnFieldProps extends FieldProps {
children: React.ReactNode;
}

export interface YAMLEditorFieldProps extends FieldProps {
onChange?: (value: string) => void;
}

export interface NameValuePair {
name: string;
value: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export { default as ResourceDropdownField } from './ResourceDropdownField';
export { default as ResourceLimitField } from './ResourceLimitField';
export { default as SwitchField } from './SwitchField';
export { default as TextAreaField } from './TextAreaField';
export { default as YAMLEditorField } from './YAMLEditorField';
export * from './field-utils';
export * from './field-types';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import * as _ from 'lodash';
import { Form, TextInputTypes } from '@patternfly/react-core';
import { FormikProps, FormikValues } from 'formik';
import { InputField, FormFooter } from '@console/shared';
import { InputField, FormFooter, YAMLEditorField } from '@console/shared';
import FormSection from '../import/section/FormSection';

const HelmInstallForm: React.FC<FormikProps<FormikValues>> = ({
Expand All @@ -22,6 +22,7 @@ const HelmInstallForm: React.FC<FormikProps<FormikValues>> = ({
helpText="A unique name for the Helm Chart release."
required
/>
<YAMLEditorField name="valuesYAML" />
</FormSection>
<FormFooter
handleReset={handleReset}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import * as yup from 'yup';
import { safeDump, safeLoad } from 'js-yaml';
import { RouteComponentProps } from 'react-router-dom';
import { Helmet } from 'react-helmet';
import { PageHeading, history } from '@console/internal/components/utils';
Expand All @@ -8,11 +9,13 @@ import { Formik } from 'formik';
import NamespacedPage, { NamespacedPageVariants } from '../NamespacedPage';
import { nameValidationSchema } from '../import/validation-schema';
import HelmInstallForm from './HelmInstallForm';
import { mockValues } from './helm-release-resources-utils';

export type HelmInstallPageProps = RouteComponentProps<{ ns?: string }>;

export type HelmInstallFormData = {
releaseName: string;
valuesYAML: string;
};

export const HelmInstallPage: React.FunctionComponent<HelmInstallPageProps> = ({ location }) => {
Expand All @@ -22,20 +25,32 @@ export const HelmInstallPage: React.FunctionComponent<HelmInstallPageProps> = ({

const initialValues: HelmInstallFormData = {
releaseName: '',
valuesYAML: safeDump(mockValues),
};

const validationSchema = yup.object().shape({
releaseName: nameValidationSchema,
});

const handleSubmit = (values, actions) => {
const { releaseName }: HelmInstallFormData = values;
const { releaseName, valuesYAML }: HelmInstallFormData = values;
let valuesObj;

try {
valuesObj = safeLoad(valuesYAML);
} catch (err) {
actions.setStatus({ submitError: `Invalid YAML - ${err}` });
return;
}

const payload = {
namespace: preselectedNamespace,
name: releaseName,
// eslint-disable-next-line @typescript-eslint/camelcase
chart_url: chartURL,
...(valuesObj ? { values: valuesObj } : {}),
};

coFetchJSON
.post('/api/helm/release', payload, null)
.then(() => {
Expand All @@ -60,8 +75,9 @@ export const HelmInstallPage: React.FunctionComponent<HelmInstallPageProps> = ({
onSubmit={handleSubmit}
onReset={history.goBack}
validationSchema={validationSchema}
render={(props) => <HelmInstallForm {...props} />}
/>
>
{(props) => <HelmInstallForm {...props} />}
</Formik>
</div>
</NamespacedPage>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,32 @@ export const flattenResources = (resources: { [kind: string]: { data: K8sResourc
}
return acc;
}, []);

export const mockValues = {
affinity: {},
fullnameOverride: '',
image: {
pullPolicy: 'IfNotPresent',
repository: 'nginx',
},
ingress: {
annotations: {},
enabled: false,
hosts: [
{
host: 'chart-example.local',
paths: [],
},
],
tls: [],
},
nameOverride: '',
nodeSelector: {},
replicaCount: 1,
resources: {},
service: {
port: 80,
type: 'ClusterIP',
},
tolerations: [],
};
152 changes: 83 additions & 69 deletions frontend/public/components/edit-yaml.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,9 @@ const EditYAML_ = connect(stateToProps)(
canDrop,
create,
yamlSamplesList,
customClass,
onChange = () => null,
hideActions = false,
} = this.props;
const klass = classNames('co-file-dropzone-container', {
'co-file-dropzone--drop-over': isOver,
Expand Down Expand Up @@ -742,7 +744,10 @@ const EditYAML_ = connect(stateToProps)(
<div className="pf-c-form">
<div className="co-p-has-sidebar">
<div className="co-p-has-sidebar__body">
<div className="yaml-editor" ref={(r) => (this.editor = r)}>
<div
className={classNames('yaml-editor', customClass)}
ref={(r) => (this.editor = r)}
>
<div className="yaml-editor__links">
{!genericYAML && (
<div className="yaml-editor__link">
Expand Down Expand Up @@ -802,75 +807,84 @@ const EditYAML_ = connect(stateToProps)(
}
/>
<div className="yaml-editor__buttons" ref={(r) => (this.buttons = r)}>
{customAlerts}
{error && (
<Alert
isInline
className="co-alert co-alert--scrollable"
variant="danger"
title="An error occurred"
>
<div className="co-pre-line">{error}</div>
</Alert>
)}
{success && (
<Alert isInline className="co-alert" variant="success" title={success} />
)}
{stale && (
<Alert
isInline
className="co-alert"
variant="info"
title="This object has been updated."
>
Click reload to see the new version.
</Alert>
{!hideActions && (
<>
{customAlerts}
{error && (
<Alert
isInline
className="co-alert co-alert--scrollable"
variant="danger"
title="An error occurred"
>
<div className="co-pre-line">{error}</div>
</Alert>
)}
{success && (
<Alert
isInline
className="co-alert"
variant="success"
title={success}
/>
)}
{stale && (
<Alert
isInline
className="co-alert"
variant="info"
title="This object has been updated."
>
Click reload to see the new version.
</Alert>
)}
<ActionGroup className="pf-c-form__group--no-top-margin">
{create && (
<Button
type="submit"
variant="primary"
id="save-changes"
onClick={() => this.save()}
>
Create
</Button>
)}
{!create && !readOnly && (
<Button
type="submit"
variant="primary"
id="save-changes"
onClick={() => this.save()}
>
Save
</Button>
)}
{!create && !genericYAML && (
<Button
type="submit"
variant="secondary"
id="reload-object"
onClick={() => this.reload()}
>
Reload
</Button>
)}
<Button variant="secondary" id="cancel" onClick={() => this.onCancel()}>
Cancel
</Button>
{download && (
<Button
type="submit"
variant="secondary"
className="pf-c-button--align-right hidden-sm hidden-xs"
onClick={() => this.download()}
>
<DownloadIcon /> Download
</Button>
)}
</ActionGroup>
</>
)}
<ActionGroup className="pf-c-form__group--no-top-margin">
{create && (
<Button
type="submit"
variant="primary"
id="save-changes"
onClick={() => this.save()}
>
Create
</Button>
)}
{!create && !readOnly && (
<Button
type="submit"
variant="primary"
id="save-changes"
onClick={() => this.save()}
>
Save
</Button>
)}
{!create && !genericYAML && (
<Button
type="submit"
variant="secondary"
id="reload-object"
onClick={() => this.reload()}
>
Reload
</Button>
)}
<Button variant="secondary" id="cancel" onClick={() => this.onCancel()}>
Cancel
</Button>
{download && (
<Button
type="submit"
variant="secondary"
className="pf-c-button--align-right hidden-sm hidden-xs"
onClick={() => this.download()}
>
<DownloadIcon /> Download
</Button>
)}
</ActionGroup>
</div>
</div>
</div>
Expand Down

0 comments on commit 9261dd1

Please sign in to comment.