157 lines
4.6 KiB
TypeScript
157 lines
4.6 KiB
TypeScript
import type { ChangeEvent } from "react";
|
|
import type { Settings, Widgets, SelectWidgetProps } from "react-awesome-query-builder";
|
|
// Figure out why routing-forms/env.d.ts doesn't work
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
//@ts-ignore
|
|
import BasicConfig from "react-awesome-query-builder/lib/config/basic";
|
|
|
|
import { EmailField } from "@calcom/ui";
|
|
|
|
import widgetsComponents from "../widgets";
|
|
|
|
const {
|
|
TextWidget,
|
|
TextAreaWidget,
|
|
MultiSelectWidget,
|
|
SelectWidget,
|
|
NumberWidget,
|
|
FieldSelect,
|
|
Conjs,
|
|
Button,
|
|
ButtonGroup,
|
|
Provider,
|
|
} = widgetsComponents;
|
|
|
|
const renderComponent = function <T1>(props: T1 | undefined, Component: React.FC<T1>) {
|
|
if (!props) {
|
|
return <div />;
|
|
}
|
|
return <Component {...props} />;
|
|
};
|
|
|
|
const settings: Settings = {
|
|
...BasicConfig.settings,
|
|
|
|
renderField: (props) => renderComponent(props, FieldSelect),
|
|
renderOperator: (props) => renderComponent(props, FieldSelect),
|
|
renderFunc: (props) => renderComponent(props, FieldSelect),
|
|
renderConjs: (props) => renderComponent(props, Conjs),
|
|
renderButton: (props) => renderComponent(props, Button),
|
|
renderButtonGroup: (props) => renderComponent(props, ButtonGroup),
|
|
renderProvider: (props) => renderComponent(props, Provider),
|
|
|
|
groupActionsPosition: "bottomCenter",
|
|
|
|
// Disable groups
|
|
maxNesting: 1,
|
|
};
|
|
|
|
// react-query-builder types have missing type property on Widget
|
|
//TODO: Reuse FormBuilder Components - FormBuilder components are built considering Cal.com design system and coding guidelines. But when awesome-query-builder renders these components, it passes its own props which are different from what our Components expect.
|
|
// So, a mapper should be written here that maps the props provided by awesome-query-builder to the props that our components expect.
|
|
const widgets: Widgets & { [key in keyof Widgets]: Widgets[key] & { type: string } } = {
|
|
...BasicConfig.widgets,
|
|
text: {
|
|
...BasicConfig.widgets.text,
|
|
factory: (props) => renderComponent(props, TextWidget),
|
|
},
|
|
textarea: {
|
|
...BasicConfig.widgets.textarea,
|
|
factory: (props) => renderComponent(props, TextAreaWidget),
|
|
},
|
|
number: {
|
|
...BasicConfig.widgets.number,
|
|
factory: (props) => renderComponent(props, NumberWidget),
|
|
},
|
|
multiselect: {
|
|
...BasicConfig.widgets.multiselect,
|
|
factory: (
|
|
props: SelectWidgetProps & {
|
|
listValues: { title: string; value: string }[];
|
|
}
|
|
) => renderComponent(props, MultiSelectWidget),
|
|
},
|
|
select: {
|
|
...BasicConfig.widgets.select,
|
|
factory: (
|
|
props: SelectWidgetProps & {
|
|
listValues: { title: string; value: string }[];
|
|
}
|
|
) => renderComponent(props, SelectWidget),
|
|
},
|
|
phone: {
|
|
...BasicConfig.widgets.text,
|
|
factory: (props) => {
|
|
if (!props) {
|
|
return <div />;
|
|
}
|
|
return <TextWidget type="tel" {...props} />;
|
|
},
|
|
valuePlaceholder: "Enter Phone Number",
|
|
},
|
|
email: {
|
|
...BasicConfig.widgets.text,
|
|
factory: (props) => {
|
|
if (!props) {
|
|
return <div />;
|
|
}
|
|
|
|
return (
|
|
<EmailField
|
|
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
|
const val = e.target.value;
|
|
props.setValue(val);
|
|
}}
|
|
containerClassName="w-full"
|
|
className="dark:placeholder:text-darkgray-600 focus:border-brand border-subtle dark:text-darkgray-900 block w-full rounded-md border-gray-300 text-sm focus:ring-black disabled:bg-gray-200 disabled:hover:cursor-not-allowed dark:bg-transparent dark:selection:bg-green-500 disabled:dark:text-gray-500"
|
|
{...props}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
};
|
|
|
|
const types = {
|
|
...BasicConfig.types,
|
|
phone: {
|
|
...BasicConfig.types.text,
|
|
widgets: {
|
|
...BasicConfig.types.text.widgets,
|
|
},
|
|
},
|
|
email: {
|
|
...BasicConfig.types.text,
|
|
widgets: {
|
|
...BasicConfig.types.text.widgets,
|
|
},
|
|
},
|
|
};
|
|
|
|
const operators = BasicConfig.operators;
|
|
operators.equal.label = operators.select_equals.label = "Equals";
|
|
operators.greater_or_equal.label = "Greater than or equal to";
|
|
operators.greater.label = "Greater than";
|
|
operators.less_or_equal.label = "Less than or equal to";
|
|
operators.less.label = "Less than";
|
|
operators.not_equal.label = operators.select_not_equals.label = "Does not equal";
|
|
operators.between.label = "Between";
|
|
|
|
delete operators.proximity;
|
|
delete operators.is_null;
|
|
delete operators.is_not_null;
|
|
|
|
/**
|
|
* Not supported with JSONLogic. Implement them and add these back -> https://github.com/jwadhams/json-logic-js/issues/81
|
|
*/
|
|
delete operators.starts_with;
|
|
delete operators.ends_with;
|
|
|
|
const config = {
|
|
conjunctions: BasicConfig.conjunctions,
|
|
operators,
|
|
types,
|
|
widgets,
|
|
settings,
|
|
};
|
|
export default config;
|