Fix routing form field input loosing focus on typing (#18381)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
This commit is contained in:
co-authored by
Udit Takkar
parent
b5bec79354
commit
ab942ed4cd
@@ -0,0 +1,163 @@
|
||||
import type { Settings } from "react-awesome-query-builder";
|
||||
import { describe, it, vi, expect } from "vitest";
|
||||
|
||||
import {
|
||||
ConfigFor,
|
||||
withRaqbSettingsAndWidgets,
|
||||
} from "../components/react-awesome-query-builder/config/uiConfig";
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock("../components/react-awesome-query-builder/widgets", () => ({
|
||||
default: {
|
||||
TextWidget: vi.fn(),
|
||||
TextAreaWidget: vi.fn(),
|
||||
MultiSelectWidget: vi.fn(),
|
||||
SelectWidget: vi.fn(),
|
||||
NumberWidget: vi.fn(),
|
||||
FieldSelect: vi.fn(),
|
||||
Conjs: vi.fn(),
|
||||
Button: vi.fn(),
|
||||
ButtonGroup: vi.fn(),
|
||||
Provider: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("@calcom/ui", () => ({
|
||||
EmailField: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("uiConfig", () => {
|
||||
const mockConfig = {
|
||||
widgets: {
|
||||
text: {
|
||||
type: "text",
|
||||
},
|
||||
textarea: {
|
||||
type: "textarea",
|
||||
},
|
||||
number: {
|
||||
type: "number",
|
||||
},
|
||||
multiselect: {
|
||||
type: "multiselect",
|
||||
},
|
||||
select: {
|
||||
type: "select",
|
||||
},
|
||||
phone: {
|
||||
type: "phone",
|
||||
},
|
||||
email: {
|
||||
type: "email",
|
||||
},
|
||||
},
|
||||
settings: {} as Settings,
|
||||
};
|
||||
|
||||
describe("withRaqbSettingsAndWidgets", () => {
|
||||
it("should add factory functions to all widgets", () => {
|
||||
const result = withRaqbSettingsAndWidgets({
|
||||
config: mockConfig,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
// Verify each widget has a factory function
|
||||
expect(result.widgets.text).toHaveProperty("factory");
|
||||
expect(result.widgets.textarea).toHaveProperty("factory");
|
||||
expect(result.widgets.number).toHaveProperty("factory");
|
||||
expect(result.widgets.multiselect).toHaveProperty("factory");
|
||||
expect(result.widgets.select).toHaveProperty("factory");
|
||||
expect(result.widgets.phone).toHaveProperty("factory");
|
||||
expect(result.widgets.email).toHaveProperty("factory");
|
||||
});
|
||||
|
||||
it("should add render functions to settings", () => {
|
||||
const result = withRaqbSettingsAndWidgets({
|
||||
config: mockConfig,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
// Verify settings have all required render functions
|
||||
expect(result.settings).toHaveProperty("renderField");
|
||||
expect(result.settings).toHaveProperty("renderOperator");
|
||||
expect(result.settings).toHaveProperty("renderFunc");
|
||||
expect(result.settings).toHaveProperty("renderConjs");
|
||||
expect(result.settings).toHaveProperty("renderButton");
|
||||
expect(result.settings).toHaveProperty("renderButtonGroup");
|
||||
expect(result.settings).toHaveProperty("renderProvider");
|
||||
});
|
||||
|
||||
it("should preserve existing widget properties while adding factory", () => {
|
||||
const configWithExistingProps = {
|
||||
...mockConfig,
|
||||
widgets: {
|
||||
...mockConfig.widgets,
|
||||
text: {
|
||||
type: "text",
|
||||
existingProp: "value",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const result = withRaqbSettingsAndWidgets({
|
||||
config: configWithExistingProps,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
expect(result.widgets.text).toHaveProperty("existingProp", "value");
|
||||
expect(result.widgets.text).toHaveProperty("factory");
|
||||
});
|
||||
|
||||
it("should set correct placeholder for phone widget", () => {
|
||||
const result = withRaqbSettingsAndWidgets({
|
||||
config: mockConfig,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
expect(result.widgets.phone).toHaveProperty("valuePlaceholder", "Enter Phone Number");
|
||||
});
|
||||
|
||||
it("should reuse same component fns for widgets - ensures remounting is not happening", () => {
|
||||
const configWithExistingProps = {
|
||||
...mockConfig,
|
||||
};
|
||||
|
||||
const result = withRaqbSettingsAndWidgets({
|
||||
config: configWithExistingProps,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
// @ts-expect-error - TODO: fix this
|
||||
const textFactory = result.widgets.text.factory;
|
||||
|
||||
const result2 = withRaqbSettingsAndWidgets({
|
||||
config: configWithExistingProps,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
// @ts-expect-error - TODO: fix this
|
||||
// Using same reference
|
||||
expect(result2.widgets.text.factory).toBe(textFactory);
|
||||
});
|
||||
|
||||
it("should reuse same component fns for settings - ensures remounting is not happening", () => {
|
||||
const configWithExistingProps = {
|
||||
...mockConfig,
|
||||
};
|
||||
|
||||
const result1 = withRaqbSettingsAndWidgets({
|
||||
config: configWithExistingProps,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
const renderFieldOnFirstCallOfWithRaqbSettingsAndWidgets = result1.settings.renderField;
|
||||
|
||||
const result2 = withRaqbSettingsAndWidgets({
|
||||
config: configWithExistingProps,
|
||||
configFor: ConfigFor.FormFields,
|
||||
});
|
||||
|
||||
expect(result2.settings.renderField).toBe(renderFieldOnFirstCallOfWithRaqbSettingsAndWidgets);
|
||||
});
|
||||
});
|
||||
});
|
||||
+12
-7
@@ -116,16 +116,21 @@ function withFactoryWidgets(widgets: WidgetsWithoutFactory) {
|
||||
return widgetsWithFactory;
|
||||
}
|
||||
|
||||
// These are components and components reference when changed causes remounting of components. So, ensure that renderField and others are defined only once
|
||||
const sharedSettingsProps: Partial<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),
|
||||
};
|
||||
|
||||
function withRenderFnsSettings(settings: Settings) {
|
||||
const settingsWithRenderFns: Settings = {
|
||||
...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),
|
||||
...sharedSettingsProps,
|
||||
};
|
||||
return settingsWithRenderFns;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user