Skip to content
This repository has been archived by the owner on Jun 14, 2019. It is now read-only.

Commit

Permalink
Merge pull request #310 from gashcrumb/issue-270
Browse files Browse the repository at this point in the history
  • Loading branch information
pure-bot[bot] authored May 18, 2019
2 parents d134302 + 3571604 commit 466f33d
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 34 deletions.
5 changes: 5 additions & 0 deletions app/ui-react/packages/auto-form/src/AutoForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export interface IAutoFormProps<T> {
* The initial value that should be set on the form
*/
initialValue: T;
/**
* If the passed in value is valid or not
*/
isInitialValid?: boolean;
/**
* String to be displayed when a required field isn't set
*/
Expand Down Expand Up @@ -63,6 +67,7 @@ export class AutoForm<T> extends React.Component<IAutoFormProps<T>> {
<Formik<T>
initialValues={initialValue}
onSubmit={onSave}
isInitialValid={this.props.isInitialValid}
validate={this.props.validate}
>
{({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,18 @@ export class IntegrationEditorForm extends React.Component<
<div className="card-pf-footer">
{this.props.backActionHref && (
<>
<ButtonLink href={this.props.backActionHref}>
<ButtonLink
id={'integration-editor-form-back-button'}
href={this.props.backActionHref}
>
<i className={'fa fa-chevron-left'} />{' '}
{this.props.i18nBackAction}
</ButtonLink>
&nbsp;
</>
)}
<ButtonLink
id={'integration-editor-form-next-button'}
onClick={this.props.submitForm}
disabled={!this.props.isValid}
as={'primary'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export class DescribeDataShapeForm extends React.Component<
<FieldLevelHelp content={this.props.i18nSelectTypeHelp} />
</ControlLabel>
<FormControl
data-testid={'describe-data-shape-form-kind-select'}
componentClass="select"
value={this.props.kind}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
Expand All @@ -96,6 +97,7 @@ export class DescribeDataShapeForm extends React.Component<
content={this.props.i18nDefinitionHelp}
/>
<TextEditor
id={'describe-data-shape-form-definition-editor'}
value={this.props.definition || ''}
onChange={(editor, data, text) =>
this.props.onDefinitionChange(text)
Expand All @@ -121,6 +123,7 @@ export class DescribeDataShapeForm extends React.Component<
/>
</ControlLabel>
<FormControl
data-testid={'describe-data-shape-form-name-text'}
type="text"
value={this.props.name}
onChange={(
Expand All @@ -139,6 +142,9 @@ export class DescribeDataShapeForm extends React.Component<
</ControlLabel>
<FormControl
type="text"
data-testid={
'describe-data-shape-form-description-text'
}
value={this.props.description}
onChange={(
event: React.ChangeEvent<HTMLInputElement>
Expand All @@ -154,14 +160,21 @@ export class DescribeDataShapeForm extends React.Component<
<div className="card-pf-footer">
{this.props.backActionHref && (
<>
<ButtonLink href={this.props.backActionHref}>
<ButtonLink
data-testid={'describe-data-shape-form-back-button'}
href={this.props.backActionHref}
>
<i className={'fa fa-chevron-left'} />{' '}
{this.props.i18nBackAction}
</ButtonLink>
&nbsp;
</>
)}
<ButtonLink onClick={this.props.onNext} as={'primary'}>
<ButtonLink
data-testid={'describe-data-shape-form-next-button'}
onClick={this.props.onNext}
as={'primary'}
>
{this.props.i18nNext}
</ButtonLink>
</div>
Expand Down
15 changes: 9 additions & 6 deletions app/ui-react/packages/ui/src/Shared/TextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { CodeMirror };
export type ITextEditor = CodeMirror.Editor;

export interface ITextEditorProps {
id?: string;
value: string;
options: { [name: string]: any };
onChange: (editor: ITextEditor, data: any, value: string) => void;
Expand All @@ -25,12 +26,14 @@ export class TextEditor extends React.Component<ITextEditorProps> {
const options = { ...this.props.options };
return (
<>
<ReactCodeMirror
value={this.props.value}
options={options}
onChange={this.props.onChange}
editorDidMount={this.props.editorDidMount}
/>
<div data-testid={this.props.id || 'codemirror'}>
<ReactCodeMirror
value={this.props.value}
options={options}
onChange={this.props.onChange}
editorDidMount={this.props.editorDidMount}
/>
</div>
</>
);
}
Expand Down
38 changes: 32 additions & 6 deletions app/ui-react/packages/utils/src/autoformHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IFormDefinition, IFormDefinitionProperty } from '@syndesis/auto-form';
import {
IConfigurationProperties,
IConfigurationProperty,
StringMap,
} from '@syndesis/models';

/**
Expand Down Expand Up @@ -54,12 +55,32 @@ export function toFormDefinitionProperty(property: IConfigurationProperty) {
} as IFormDefinitionProperty;
}

export function getInitialValues(properties: IConfigurationProperties) {
const configuredProperties = {};
/**
* Returns a new configuredProperties object with any default values set from
* the given definition if they aren't set already
* @param properties
* @param initial
*/
export function applyInitialValues(
properties: IConfigurationProperties,
initial?: StringMap<string>
) {
const configuredProperties =
typeof initial !== 'undefined' ? { ...initial } : {};
Object.keys(properties).forEach(key => {
const property = properties[key];
if (property.value || property.defaultValue) {
configuredProperties[key] = property.value || property.defaultValue;
// `property.value` being set is deprecated, defaultValue takes precedence
if (
typeof property.value !== 'undefined' &&
typeof configuredProperties[key] === 'undefined'
) {
configuredProperties[key] = property.value;
}
if (
typeof property.defaultValue !== 'undefined' &&
typeof configuredProperties[key] === 'undefined'
) {
configuredProperties[key] = property.defaultValue;
}
});
return configuredProperties;
Expand All @@ -72,8 +93,13 @@ export function validateConfiguredProperties(
if (typeof values === 'undefined') {
return false;
}
const allRequiredSet = Object.keys(properties)
.filter(key => properties[key].required)
const allRequired = Object.keys(properties).filter(
key => properties[key].required
);
if (allRequired.length === 0) {
return true;
}
const allRequiredSet = allRequired
.map(key => typeof values[key] !== 'undefined')
.reduce((prev, curr) => curr, false);
return allRequiredSet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,11 @@ export class ConfigureActionPage extends React.Component<
<WithConfigurationForm
connection={connection}
actionId={actionId}
oldAction={oldStepConfig!.action!}
oldAction={
oldStepConfig && oldStepConfig.action
? oldStepConfig!.action!
: undefined
}
configurationStep={stepAsNumber}
initialValue={configuredProperties}
onUpdatedIntegration={onUpdatedIntegration}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
PageSectionLoader,
} from '@syndesis/ui';
import {
getInitialValues,
applyInitialValues,
toFormDefinition,
validateConfiguredProperties,
WithLoader,
Expand Down Expand Up @@ -76,7 +76,7 @@ export interface IWithConfigurationFormProps {
*/
actionId: string;

oldAction: Action;
oldAction?: Action;
/**
* for actions whose configuration must be performed in multiple steps,
* indicates the current step.
Expand Down Expand Up @@ -129,30 +129,39 @@ export class WithConfigurationForm extends React.Component<
values: { [key: string]: string },
actions: any
): Promise<void> => {
action =
typeof this.props.oldAction !== 'undefined'
? applyUserDefinedDataShapesToAction(this.props.oldAction, {
...action,
descriptor,
})
: action;
await this.props.onUpdatedIntegration({
action: applyUserDefinedDataShapesToAction(this.props.oldAction, {
...action,
descriptor,
}),
action,
moreConfigurationSteps,
values,
});
actions.setSubmitting(false);
};
const key = JSON.stringify(definition);
const allRequiredSet = validateConfiguredProperties(
const initialValue = applyInitialValues(
definition,
this.props.initialValue
);
const isInitialValid = validateConfiguredProperties(
definition,
initialValue
);
return (
<AutoForm<{ [key: string]: string }>
i18nRequiredProperty={'* Required field'}
definition={toFormDefinition(definition)}
initialValue={this.props.initialValue || getInitialValues(definition)}
initialValue={initialValue}
isInitialValid={isInitialValid}
onSave={onSave}
validate={(values: { [name: string]: any }): any => {
return true;
}}
validate={(values: { [name: string]: any }): any =>
validateConfiguredProperties(definition, values)
}
key={key}
>
{({ dirty, fields, handleSubmit, isValid, submitForm }) => (
Expand All @@ -161,7 +170,7 @@ export class WithConfigurationForm extends React.Component<
i18nFormTitle={`${action.name} - ${action.description}`}
i18nBackAction={'Choose Action'}
i18nNext={'Next'}
isValid={allRequiredSet || isValid}
isValid={isValid}
submitForm={submitForm}
handleSubmit={handleSubmit}
backActionHref={this.props.chooseActionHref}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import {
getActionSteps,
} from '@syndesis/api';
import { AutoForm } from '@syndesis/auto-form';
import { StepKind } from '@syndesis/models';
import { ConfigurationProperty, StepKind } from '@syndesis/models';
import { IntegrationEditorForm } from '@syndesis/ui';
import { toFormDefinition } from '@syndesis/utils';
import {
applyInitialValues,
toFormDefinition,
validateConfiguredProperties,
} from '@syndesis/utils';
import * as React from 'react';

export interface IWithConfigurationFormChildrenProps {
Expand Down Expand Up @@ -91,9 +95,7 @@ export class WithConfigurationForm extends React.Component<
let step = this.props.step.properties
? this.props.step
: ALL_STEPS.find(s => s.stepKind === this.props.step.stepKind);

let definition;

let definition: { [key: string]: ConfigurationProperty };
// if step is undefined, maybe we are dealing with an extension
if (!step) {
const steps = getActionSteps(this.props.step.action!.descriptor!);
Expand All @@ -103,12 +105,24 @@ export class WithConfigurationForm extends React.Component<
} else {
definition = step.properties;
}
const initialValue = applyInitialValues(
definition,
this.props.step.configuredProperties
);
const isInitialValid = validateConfiguredProperties(
definition,
initialValue
);
return (
<AutoForm<{ [key: string]: string }>
i18nRequiredProperty={'* Required field'}
definition={toFormDefinition(definition)}
initialValue={this.props.step.configuredProperties || {}}
initialValue={initialValue}
isInitialValid={isInitialValid}
onSave={onSave}
validate={(values: { [name: string]: any }): any =>
validateConfiguredProperties(definition, values)
}
key={this.props.step.id}
>
{({ fields, handleSubmit, isSubmitting, isValid, submitForm }) =>
Expand Down

0 comments on commit 466f33d

Please sign in to comment.