Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/syndesisio/syndesis-react
Browse files Browse the repository at this point in the history
…into TTOOLS-616
  • Loading branch information
blafond committed May 23, 2019
2 parents 7c892b3 + 2025b97 commit cf41280
Show file tree
Hide file tree
Showing 129 changed files with 2,404 additions and 824 deletions.
119 changes: 119 additions & 0 deletions app/ui-react/packages/api/src/WithFilterOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { DataShape, FilterOptions, Op } from '@syndesis/models';
import * as React from 'react';
import { IFetchState } from './Fetch';
import { SyndesisFetch } from './SyndesisFetch';

export interface IWithFilterOptionsProps {
dataShape: DataShape;
children(props: IFetchState<FilterOptions>): any;
}

function getDefaultOps() {
return [
{
label: 'equals',
operator: '==',
},
{
label: 'equals (ignores case)',
operator: '=~',
},
{
label: 'not equals',
operator: '==',
},
{
operator: '<',
},
{
operator: '<=',
},
{
operator: '>',
},
{
operator: '>=',
},
{
label: 'contains',
operator: 'contains',
},
{
label: 'contains (ignore case)',
operator: '~~',
},
{
label: 'not contains',
operator: 'not contains',
},
{
label: 'matches',
operator: 'regex',
},
{
label: 'not matches',
operator: 'not regex',
},
{
label: 'in',
operator: 'in',
},
{
label: 'not in',
operator: 'not in',
},
];
}

export interface IOp {
label: string;
operator?: string;
value?: string;
}

function convertOps(ops: Op[]): Op[] {
const answer = [];
for (const op of ops) {
// guard against blank label
const label = op.label || (op as IOp).value || op.operator;
const newOp = {
label,
value: (op as IOp).value || op.operator,
} as IOp;
answer.push(newOp);
}
return answer;
}

export class WithFilterOptions extends React.Component<
IWithFilterOptionsProps
> {
public render() {
const defaultValue = {
ops: [],
paths: [],
};
return (
<SyndesisFetch<FilterOptions>
body={this.props.dataShape}
defaultValue={defaultValue}
method={'POST'}
url={`/integrations/filters/options`}
>
{({ response }) => {
const ops = response.data.ops!.length
? response.data.ops!
: getDefaultOps();
const data = {
ops: convertOps(ops),
paths: response.data.paths || [],
};
return this.props.children({
...response,
data,
});
}}
</SyndesisFetch>
);
}
}
47 changes: 47 additions & 0 deletions app/ui-react/packages/api/src/WithUserHelpers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from 'react';
import { ApiContext, IApiContext } from './ApiContext';
import { callFetch } from './callFetch';

export interface IWithUserHelpersChildrenProps {
logout(): Promise<any>;
}
export interface IWithUserHelpersProps {
children(props: IWithUserHelpersChildrenProps): any;
}

export class WithUserHelpersWrapped extends React.Component<
IWithUserHelpersProps & IApiContext
> {
constructor(props: IWithUserHelpersProps & IApiContext) {
super(props);
this.logout = this.logout.bind(this);
}

public async logout() {
const response = await callFetch({
headers: {
...this.props.headers,
responseType: 'arraybuffer',
},
method: 'GET',
url: `${process.env.PUBLIC_URL}/logout`,
});
return await response.body;
}

public render() {
return this.props.children({
logout: this.logout,
});
}
}

export const WithUserHelpers: React.FunctionComponent<
IWithUserHelpersProps
> = props => {
return (
<ApiContext.Consumer>
{apiContext => <WithUserHelpersWrapped {...props} {...apiContext} />}
</ApiContext.Consumer>
);
};
2 changes: 2 additions & 0 deletions app/ui-react/packages/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export * from './WithExtension';
export * from './WithExtensionHelpers';
export * from './WithExtensionIntegrations';
export * from './WithExtensions';
export * from './WithFilterOptions';
export * from './WithIntegration';
export * from './WithIntegrationHelpers';
export * from './WithIntegrationMetrics';
Expand All @@ -40,6 +41,7 @@ export * from './WithPolling';
export * from './WithServerEvents';
export * from './WithSteps';
export * from './WithUser';
export * from './WithUserHelpers';
export * from './WithVdbModel';
export * from './WithViewEditorStates';
export * from './WithViews';
Expand Down
97 changes: 44 additions & 53 deletions app/ui-react/packages/auto-form/src/AutoForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Formik, FormikErrors } from 'formik';
import { Formik, FormikErrors, FormikProps } from 'formik';
import * as React from 'react';
import { FormBuilder } from './FormBuilder';
import { IFormDefinition, IFormErrors } from './models';
import { IAutoFormActions, IFormDefinition, IFormErrors } from './models';

export interface IAutoFormProps<T> {
/**
Expand All @@ -20,6 +20,11 @@ export interface IAutoFormProps<T> {
* If all fields in the form are required or not
*/
allFieldsRequired?: boolean;
/**
* Map of custom components, each key maps to the 'type'
* property of an IFormDefinitionProperty
*/
customComponents?: { [type: string]: any };
/**
* String to be displayed when a required field isn't set
*/
Expand All @@ -31,35 +36,29 @@ export interface IAutoFormProps<T> {
/**
* Callback function that will be called when the form is submitted
*/
onSave: (value: T, actions: any) => void;
onSave?: (value: T, autoFormBag: IAutoFormActions<T>) => void;
/**
* Validation function called whenever a change or blur event occurs on the form
*/
validate?: (value: T | any) => IFormErrors | Promise<any> | undefined;
validate?: (
value: T | any
) => IFormErrors<T> | Promise<IFormErrors<T>> | undefined;
/**
* Child component that will receive the form fields and submit handler
*/
children: (state: IAutoFormChildrenProps) => any;
children: (props: IAutoFormChildrenProps<T> & FormikProps<T>) => any;
}

export interface IAutoFormChildrenProps {
export interface IAutoFormChildrenProps<T> {
/**
* Fragment containing all of the form fields
*/
fields: JSX.Element;
fieldsAsArray: JSX.Element[];
/**
* Function to trigger a form submit which will then trigger onSave
*/
handleSubmit: (e?: any) => void;
dirty: boolean;
isSubmitting: boolean;
isValid: boolean;
isValidating: boolean;
resetForm: (nextValues?: any) => void;
submitForm: () => void;
validateForm: () => Promise<FormikErrors<any>>;
values: any;
errors: any;
validateForm: () => Promise<IFormErrors<T> | FormikErrors<T>>;
}

export class AutoForm<T> extends React.Component<IAutoFormProps<T>> {
Expand All @@ -68,64 +67,56 @@ export class AutoForm<T> extends React.Component<IAutoFormProps<T>> {
<FormBuilder
definition={this.props.definition}
initialValue={this.props.initialValue}
onSave={this.props.onSave}
customComponents={this.props.customComponents || {}}
i18nRequiredProperty={this.props.i18nRequiredProperty}
>
{({ initialValue, fields, onSave, getField }) => (
{({ initialValue, propertiesArray, getField }) => (
<Formik<T>
initialValues={initialValue}
onSubmit={onSave}
onSubmit={
this.props.onSave ||
(() => {
/* todo right now silently ignore */
})
}
isInitialValid={this.props.isInitialValid}
validate={this.props.validate}
>
{({
handleSubmit,
values,
touched,
dirty,
errors,
isValid,
isValidating,
isSubmitting,
resetForm,
validateForm,
submitForm,
}) =>
this.props.children({
{({ values, touched, dirty, errors, ...rest }) => {
const propertyComponents = propertiesArray.map(property => {
const err =
typeof errors === 'object'
? errors
: { [property.name]: errors };
return getField({
allFieldsRequired: this.props.allFieldsRequired || false,
errors: err as IFormErrors<T>,
property,
value: (values || {})[property.name],
...rest,
});
});
return this.props.children({
dirty,
errors,
fields: (
<React.Fragment>
{this.props.i18nFieldsStatusText && (
<p
className="form-group fields-status-pf"
className="fields-status-pf"
dangerouslySetInnerHTML={{
__html: this.props.i18nFieldsStatusText,
}}
/>
)}
{fields.map(property =>
getField({
allFieldsRequired:
this.props.allFieldsRequired || false,
errors,
property,
touched,
value: (values || {})[property.name],
})
)}
{propertyComponents}
</React.Fragment>
),
handleSubmit,
isSubmitting,
isValid,
isValidating,
resetForm,
submitForm,
validateForm,
fieldsAsArray: propertyComponents,
values,
})
}
...(rest as FormikProps<T>),
});
}}
</Formik>
)}
</FormBuilder>
Expand Down
Loading

0 comments on commit cf41280

Please sign in to comment.