Skip to content

Commit

Permalink
Change DateField and SelectField
Browse files Browse the repository at this point in the history
  • Loading branch information
ljmotta committed Dec 20, 2024
1 parent 5124525 commit 80be77a
Show file tree
Hide file tree
Showing 15 changed files with 437 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@
export interface FormElement {
reactImports: string[];
pfImports: string[];

pfIconImports?: string[];
requiredCode?: string[];

ref: InputReference;

stateCode: string;
jsxCode: string;
isReadonly: boolean;
Expand All @@ -33,6 +31,7 @@ export interface FormElement {
abstract class AbstractFormElement implements FormElement {
jsxCode: string;
pfImports: string[];
pfIconImports?: string[];
reactImports: string[];
requiredCode?: string[];
ref: InputReference;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ const AutoForm: React.FC<AutoFormProps> = (props) => {
const inputs: FormElement[] = renderFormInputs(props.schema);

let pfImports: string[] = [];
let pfIconImports: string[] = [];
let reactImports: string[] = ["useCallback", "useEffect"];
let staticCodeArray: string[] = [];

inputs.forEach((input) => {
pfImports = union(pfImports, input.pfImports);
pfIconImports = union(pfIconImports, input.pfIconImports);
reactImports = union(reactImports, input.reactImports);
staticCodeArray = union(staticCodeArray, input.requiredCode);
});
Expand All @@ -62,7 +64,8 @@ const AutoForm: React.FC<AutoFormProps> = (props) => {

const formTemplate = `
import React, { ${reactImports.join(", ")} } from "react";
import { ${pfImports.join(", ")} } from "@patternfly/react-core";
import { ${pfImports.join(", ")} } from "@patternfly/react-core";
${pfIconImports.length > 0 ? `import { ${pfIconImports.join(", ")} } from "@patternfly/react-icons";` : ""}
const ${formName}: React.FC<any> = ( props:any ) => {
const [formApi, setFormApi] = useState<any>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,9 @@ const CheckBoxGroup: React.FC<CheckBoxGroupProps> = (props: CheckBoxGroupProps)
aria-label={'${props.name}'}
label={'${props.transform ? props.transform(value) : value}'}
isDisabled={${props.disabled || false}}
isChecked={${ref.stateName}.indexOf('${value}') != -1}
onChange={() => handleCheckboxGroupChange('${value}', ${ref.stateName}, ${ref.stateSetter})}
isChecked={${ref.stateName}.indexOf('${value}') !== -1}
onChange={${props.itemProps?.isListItem ? getListItemOnChange({ itemProps: props.itemProps, name: props.name, callback: (internalValue: string) => `handleCheckboxGroupChange(${internalValue}, ${ref.stateName}, ${ref.stateSetter})`, overrideNewValue: `'${value}'` }) : `() => handleCheckboxGroupChange('${value}', ${ref.stateName}, ${ref.stateSetter})`}}
value={${props.itemProps?.isListItem ? getListItemValue({ itemProps: props.itemProps, name: props.name }) : `'${value}'`}}
onChange={${props.itemProps?.isListItem ? getListItemOnChange({ itemProps: props.itemProps, name: props.name, callback: (internalValue: string) => `handleCheckboxGroupChange('${internalValue}', ${ref.stateName}, ${ref.stateSetter})`, overrideNewValue: `'${value}'` }) : `handleCheckboxGroupChange('${value}', ${ref.stateName}, ${ref.stateSetter})`}}
/>`;
})
.join("\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { buildDefaultInputElement, getInputReference, renderField } from "./util
import { useAddFormElementToContext } from "./CodeGenContext";
import { DATE_FUNCTIONS, TIME_FUNCTIONS } from "./staticCode/staticCodeBlocks";
import { DATE } from "./utils/dataTypes";
import { getListItemName, getListItemOnChange, getListItemValue, ListItemProps } from "./rendering/ListItemField";

export type DateFieldProps = HTMLFieldProps<
Date,
Expand All @@ -35,6 +36,7 @@ export type DateFieldProps = HTMLFieldProps<
required: boolean;
max?: Date;
min?: Date;
itemProps: ListItemProps;
}
>;

Expand All @@ -52,19 +54,34 @@ const Date: React.FC<DateFieldProps> = (props: DateFieldProps) => {
<DatePicker
id={'date-picker-${props.id}'}
isDisabled={${props.disabled || false}}
name={'${props.name}'}
onChange={newDate => onDateChange(newDate, ${ref.stateSetter}, ${ref.stateName})}
value={parseDate(${ref.stateName})}
name={${props.itemProps?.isListItem ? getListItemName({ itemProps: props.itemProps, name: props.name }) : `'${props.name}'`}}
onChange={${
props.itemProps?.isListItem
? getListItemOnChange({
itemProps: props.itemProps,
name: props.name,
callback: (value) => `onDateChange(${value}, ${ref.stateSetter}, ${ref.stateName})`,
})
: `newDate => onDateChange(newDate, ${ref.stateSetter}, ${ref.stateName})`
}}
value={${props.itemProps?.isListItem ? getListItemValue({ itemProps: props.itemProps, name: props.name, callback: (value: string) => `parseDate(${value})` }) : `parseDate(${ref.stateName})`}}
/>
<TimePicker
id={'time-picker-${props.id}'}
isDisabled={${props.disabled || false}}
name={'${props.name}'}
onChange={(time, hours?, minutes?) => onTimeChange(time, ${ref.stateSetter}, ${
ref.stateName
}, hours, minutes)}
name={${props.itemProps?.isListItem ? getListItemName({ itemProps: props.itemProps, name: props.name }) : `'${props.name}'`}}
onChange={${
props.itemProps?.isListItem
? getListItemOnChange({
itemProps: props.itemProps,
name: props.name,
callback: (_) => `onTimeChange(time, ${ref.stateSetter}, ${ref.stateName}, hours, minutes)`,
overrideParam: "(time, hours?, minutes?)",
})
: `(time, hours?, minutes?) => onTimeChange(time, ${ref.stateSetter}, ${ref.stateName}, hours, minutes)`
}}
style={{ width: '120px' }}
time={parseTime(${ref.stateName})}
time={${props.itemProps?.isListItem ? getListItemValue({ itemProps: props.itemProps, name: props.name, callback: (value: string) => `parseTime(${value})` }) : `parseTime(${ref.stateName})`}}
/>
</InputGroup>
</FlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,11 @@ const List: React.FC<ListFieldProps> = (props: ListFieldProps) => {
</div>
</div>`;

// TODO ADD PLUS AND MINUS ICONS
const element: FormInput = {
ref,
pfImports: [...new Set(["Split", "SplitItem", "Button", ...(listItem?.pfImports ?? [])])],
pfIconImports: [...new Set(["PlusCircleIcon", "MinusCircleIcon", ...(listItem?.pfIconImports ?? [])])],
reactImports: [...new Set([...(listItem?.reactImports ?? [])])],
requiredCode: [...new Set([...(listItem?.requiredCode ?? [])])],
// requiredIcons: ["PlusCircleIcon", "MinusCircleIcon"],
jsxCode,
stateCode: getStateCode(ref.stateName, ref.stateSetter, "any[]", "[]"),
isReadonly: props.disabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import { FormInput, InputReference } from "../api";
import { getInputReference, getStateCode, getStateCodeFromRef, NS_SEPARATOR, renderField } from "./utils/Utils";
import { MULTIPLE_SELECT_FUNCTIONS, SELECT_FUNCTIONS } from "./staticCode/staticCodeBlocks";
import { ARRAY, STRING } from "./utils/dataTypes";
import { getListItemName, getListItemOnChange, getListItemValue, ListItemProps } from "./rendering/ListItemField";

export type SelectInputProps = HTMLFieldProps<
string | string[],
HTMLDivElement,
{
allowedValues?: string[];
transform?(value: string): string;
itemProps?: ListItemProps;
}
>;

Expand Down Expand Up @@ -75,17 +77,15 @@ const Select: React.FC<SelectInputProps> = (props: SelectInputProps) => {
isRequired={${props.required}}
><Select
id={'${props.id}'}
name={'${props.name}'}
name={${props.itemProps?.isListItem ? getListItemName({ itemProps: props.itemProps, name: props.name }) : `'${props.name}'`}}
variant={SelectVariant.${isArray ? "typeaheadMulti" : "single"}}
isDisabled={${props.disabled || false}}
placeholderText={'${props.placeholder || ""}'}
isOpen={${expandedStateName}}
selections={${ref.stateName}}
onToggle={(isOpen) => ${expandedStateNameSetter}(isOpen)}
onSelect={(event, value, isPlaceHolder) => {
${hanldeSelect}
}}
value={${ref.stateName}}
onSelect={${props.itemProps?.isListItem ? getListItemOnChange({ itemProps: props.itemProps, name: props.name, callback: (value: string) => `${hanldeSelect}`, overrideParam: "(event, value, isPlaceHolder)" }) : `(event, value, isPlaceHolder) => ${hanldeSelect}`}}
value={${props.itemProps?.isListItem ? getListItemValue({ itemProps: props.itemProps, name: props.name }) : ref.stateName}}
>
${selectedOptions.join("\n")}
</Select></FormGroup>`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,18 @@ export const getListItemName = ({ itemProps, name }: { itemProps: ListItemProps;
* `listStateName[index]`
* `listStateName[index].itemName.`
*/
export const getListItemValue = ({ itemProps, name }: { itemProps: ListItemProps; name: string }) => {
export const getListItemValue = ({
itemProps,
name,
callback,
}: {
itemProps: ListItemProps;
name: string;
callback?: (value: string) => string;
}) => {
const { itemName, isNested } = getItemNameAndWithIsNested(name);
return `${itemProps?.listStateName}[${itemProps?.indexVariableName}]${isNested ? `.${itemName}` : ""}`;
const property = `${itemProps?.listStateName}[${itemProps?.indexVariableName}]${isNested ? `.${itemName}` : ""}`;
return `${callback ? callback(property) : property}`;
};

/**
Expand All @@ -78,17 +87,23 @@ export const getListItemOnChange = ({
name,
callback,
overrideNewValue,
overrideParam,
}: {
itemProps: ListItemProps;
name: string;
callback?: (value: string) => string;
overrideParam?: string;
overrideNewValue?: string;
}) => {
const { itemName, isNested } = getItemNameAndWithIsNested(name);
return `
newValue => ${itemProps?.listStateSetter}(s => { const newState = [...s];
newState[${itemProps?.indexVariableName}]${isNested ? `.${itemName}` : ""} = ${callback ? callback(overrideNewValue ? overrideNewValue : "newValue") : overrideNewValue ? overrideNewValue : "newValue"};
return newState; })`;
${overrideParam ? overrideParam : "newValue"} => {
${itemProps?.listStateSetter}(s => {
const newState = [...s];
newState[${itemProps?.indexVariableName}]${isNested ? `.${itemName}` : ""} = ${callback ? callback(overrideNewValue ? overrideNewValue : "newValue") : overrideNewValue ? overrideNewValue : "newValue"};
return newState;
})
}`;
};

export interface Props {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const getStateCode = (

type DefaultInputProps = {
pfImports: string[];
pfIconImports?: string[];
inputJsxCode: string;
ref: InputReference;
requiredCode?: string[];
Expand All @@ -65,6 +66,7 @@ type WrapperProps = {

export const buildDefaultInputElement = ({
pfImports,
pfIconImports,
inputJsxCode,
ref,
wrapper,
Expand All @@ -86,6 +88,7 @@ export const buildDefaultInputElement = ({
return {
ref,
pfImports,
pfIconImports,
reactImports: ["useState"],
requiredCode: requiredCode,
jsxCode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe("<CheckBoxGroupField> tests", () => {
aria-label={'${props.name}'}`;
expect(formElement.jsxCode).toContain(checkbox);
expect(formElement.jsxCode).toContain(`label={'${value}'}`);
expect(formElement.jsxCode).toContain(`isChecked={${formElement.ref.stateName}.indexOf('${value}') != -1}`);
expect(formElement.jsxCode).toContain(`isChecked={${formElement.ref.stateName}.indexOf('${value}') !== -1}`);
expect(formElement.jsxCode).toContain(
`onChange={() => handleCheckboxGroupChange('${value}', ${formElement.ref.stateName}, ${formElement.ref.stateSetter})}`
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@ describe("<ListField> tests", () => {
friends: { type: Array },
"friends.$": Object,
"friends.$.name": { type: String },
"friends.$.age": { type: Number },
"friends.$.country": { type: String, allowedValues: ["US", "Brazil"] },
"friends.$.married": { type: Boolean },
"friends.$.know": {
type: Array,
allowedValues: ["Java", "Node", "Docker"],
uniforms: {
checkboxes: true,
},
},
"friends.$.know.$": String,
"friends.$.areas": {
type: String,
allowedValues: ["Developer", "HR", "UX"],
},
"friends.$.birthday": { type: Date },
};

const props: AutoFormProps = {
Expand All @@ -42,37 +58,8 @@ describe("<ListField> tests", () => {
placeholder: true,
};

// const props = {
// id: "id",
// label: "friends",
// name: "friends",
// disabled: false,
// onChange: jest.fn(),
// maxCount: 10,
// };

const { container } = render(<AutoForm {...props} />);

// const { container, formElement } = renderField(ListField, props, schema);

expect(container).toMatchSnapshot();

// expect(formElement.reactImports).toContain("useState");
// expect(formElement.pfImports).toContain("FormGroup");
// expect(formElement.pfImports).toContain("TextInput");

// expect(formElement.ref.binding).toBe(props.name);
// expect(formElement.ref.stateName).toBe(props.name);
// expect(formElement.ref.stateSetter).toBe(`set__${props.name}`);

// expect(formElement.jsxCode).not.toBeNull();
// expect(formElement.jsxCode).toContain("label={'age'}");
// expect(formElement.jsxCode).toContain("name={'age'}");
// expect(formElement.jsxCode).toContain("isDisabled={false}");

// expect(formElement.jsxCode).toContain(`step={1}`);
// expect(formElement.jsxCode).toContain(`min={${props.min}}`);
// expect(formElement.jsxCode).toContain(`max={${props.max}}`);
// expect(formElement.stateCode).not.toBeNull();
});
});
Loading

0 comments on commit 80be77a

Please sign in to comment.