PromucFlow_constructor/app/client/src/components/propertyControls/BaseControl.tsx
balajisoundar 5db417f58b
chore: Custom widget (alpha) (#27571)
The alpha version of the Custom widget that takes a user component and
renders it on the app.

Fixes https://github.com/appsmithorg/appsmith/issues/28601

#### Type of change

- New feature (non-breaking change which adds functionality)

## Testing

#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [ ] Manual
- [ ] JUnit
- [ ] Jest
- [x] Cypress
>
>
#### Test Plan
> Add Testsmith test cases links that relate to this PR
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] PR is being merged under a feature flag
`release_custom_widgets_enabled`


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [ ] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed
2023-11-14 10:03:37 +05:30

141 lines
4.3 KiB
TypeScript

/***
* Controls are rendered in the property panel from the property config
* Controls are higher order components that update a widgets property
*/
import { Component } from "react";
import type { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
import type { PropertyPaneControlConfig } from "constants/PropertyControlConstants";
import type { CodeEditorExpected } from "components/editorComponents/CodeEditor";
import type { AdditionalDynamicDataTree } from "utils/autocomplete/customTreeTypeDefCreator";
export type ControlMethods = Record<
"canDisplayValueInUI" | "shouldValidateValueOnDynamicPropertyOff",
| typeof BaseControl.canDisplayValueInUI
| typeof BaseControl.shouldValidateValueOnDynamicPropertyOff
>;
// eslint-disable-next-line @typescript-eslint/ban-types
class BaseControl<P extends ControlProps, S = {}> extends Component<P, S> {
shoudUpdateProperty(propertyValue: unknown) {
return !(
(this.props.propertyValue === undefined &&
propertyValue === this.props.defaultValue) ||
!(this.props.propertyValue !== propertyValue)
);
}
updateProperty(
propertyName: string,
propertyValue: any,
isUpdatedViaKeyboard?: boolean,
) {
if (
this.shoudUpdateProperty(propertyValue) &&
this.props.onPropertyChange
) {
this.props.onPropertyChange(
propertyName,
propertyValue,
isUpdatedViaKeyboard,
);
}
}
deleteProperties(propertyPaths: string[]) {
if (this.props.deleteProperties) {
this.props.deleteProperties(propertyPaths);
}
}
batchUpdatePropertiesWithAssociatedUpdates = (
updates: { propertyName: string; propertyValue: any }[],
) => {
if (this.props.onBatchUpdateWithAssociatedUpdates) {
this.props.onBatchUpdateWithAssociatedUpdates(
updates.filter(({ propertyValue }) =>
this.shoudUpdateProperty(propertyValue),
),
);
}
};
batchUpdateProperties = (updates: Record<string, unknown>) => {
if (this.props.onBatchUpdateProperties) {
this.props.onBatchUpdateProperties(updates);
}
};
static getControlType() {
return "BASE_CONTROL";
}
// Checks whether a particular value can be displayed UI from JS edit mode
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static canDisplayValueInUI(config: ControlData, value: any): boolean {
return false;
}
//checks whether we need to validate the value when swtiching from js mode to non js mode
static shouldValidateValueOnDynamicPropertyOff(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
config?: ControlData,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
value?: any,
): boolean {
return true;
}
// Only applicable for JSONFormComputeControl & ComputeTablePropertyControl
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static getInputComputedValue(value: string, widgetName: string): string {
return "";
}
}
export interface ControlBuilder<T extends ControlProps> {
buildPropertyControl(controlProps: T): JSX.Element;
}
export interface ControlProps extends ControlData, ControlFunctions {
key?: string;
additionalAutoComplete?: AdditionalDynamicDataTree;
isSearchResult?: boolean;
}
export interface ControlData
extends Omit<PropertyPaneControlConfig, "additionalAutoComplete" | "label"> {
propertyValue?: any;
defaultValue?: any;
errorMessage?: string;
expected?: CodeEditorExpected;
evaluatedValue: any;
widgetProperties: any;
useValidationMessage?: boolean;
parentPropertyName: string;
parentPropertyValue: unknown;
additionalDynamicData: AdditionalDynamicDataTree;
label: string;
additionalControlData?: Record<string, unknown>;
}
export interface ControlFunctions {
onPropertyChange?: (
propertyName: string,
propertyValue: string,
isUpdatedViaKeyboard?: boolean,
isDynamicPropertyPath?: boolean,
) => void;
onBatchUpdateWithAssociatedUpdates?: (
updates: {
propertyName: string;
propertyValue: string;
}[],
isUpdatedViaKeyboard?: boolean,
) => void;
onBatchUpdateProperties?: (updates: Record<string, unknown>) => void;
openNextPanel: (props: any) => void;
deleteProperties: (propertyPaths: string[]) => void;
theme: EditorTheme;
hideEvaluatedValue?: boolean;
}
export default BaseControl;