feat: widget property setters (#23441)
## Description
- This PR adds setter methods to update widget property
programmatically.
Example:-
`Input1.setText("setter methods are cool!");`
Docs link :
https://docs.appsmith.com/reference/widgets
For any selected widget check the `Methods` section
#### PR fixes following issue(s)
Fixes
#### Type of change
- New feature (non-breaking change which adds functionality)
## Testing
>
#### How Has This Been Tested?
- [x] Manual
- [x] Jest
- [x] Cypress
>
>
#### Test Plan
https://github.com/appsmithorg/TestSmith/issues/2409
#### Issues raised during DP testing
- [x] [Errors are not logged in the
debugger](https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1564017346)
separate GitHub issue
https://github.com/appsmithorg/appsmith/issues/24609
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1564155545
( `setVisibility("false")` )
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1580525843
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1576582825
- Blocker for testing
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1577956441
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1577930108
- Not a issue (lint error query)
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1593471791
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1591440488
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1586747864
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1596738201
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1598541537
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1611413076
- [x]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1612621567
- [ ]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1619654507
- [ ]
https://github.com/appsmithorg/appsmith/pull/23441#issuecomment-1621256722
>
>
## Checklist:
#### Dev activity
- [ ] My code follows the style guidelines of this project
- [ ] 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
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag
#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Test-plan-implementation#speedbreaker-features-to-consider-for-every-change)
have been covered
- [x] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans/_edit#areas-of-interest)
- [x] 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
---------
Co-authored-by: Rishabh Rathod <rishabh.rathod@appsmith.com>
This commit is contained in:
parent
00c5c6857e
commit
2fc20cfe8e
|
|
@ -0,0 +1,56 @@
|
|||
import {
|
||||
entityExplorer,
|
||||
jsEditor,
|
||||
agHelper,
|
||||
draggableWidgets,
|
||||
locators,
|
||||
propPane,
|
||||
} from "../../../../support/Objects/ObjectsCore";
|
||||
|
||||
const jsObjectBody = `export default {
|
||||
myVar1: [],
|
||||
myVar2: {},
|
||||
myFun1(){
|
||||
|
||||
},
|
||||
myFun2: async () => {
|
||||
//use async-await or promises
|
||||
}
|
||||
}`;
|
||||
|
||||
describe("Autocomplete tests for setters", () => {
|
||||
it("1. Check if setters are present in autocomplete for widgets in JsObject", () => {
|
||||
entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 200, 200);
|
||||
jsEditor.CreateJSObject(jsObjectBody, {
|
||||
paste: true,
|
||||
completeReplace: true,
|
||||
toRun: false,
|
||||
shouldCreateNewJSObj: true,
|
||||
prettify: false,
|
||||
});
|
||||
|
||||
agHelper.GetNClick(jsEditor._lineinJsEditor(5));
|
||||
agHelper.TypeText(locators._codeMirrorTextArea, "Button1");
|
||||
|
||||
agHelper.GetElementsNAssertTextPresence(
|
||||
locators._hints,
|
||||
"Button1.setColor()",
|
||||
);
|
||||
|
||||
//For table widget
|
||||
entityExplorer.DragDropWidgetNVerify(draggableWidgets.TABLE, 500, 300);
|
||||
entityExplorer.SelectEntityByName("JSObject1");
|
||||
agHelper.GetNClick(jsEditor._lineinJsEditor(5));
|
||||
agHelper.RemoveCharsNType(locators._codeMirrorTextArea, 7, "Table1.set");
|
||||
|
||||
agHelper.GetElementsNAssertTextPresence(locators._hints, "setData()");
|
||||
});
|
||||
|
||||
it("2. Check if setters are present in autocomplete for widgets in property Pane", () => {
|
||||
entityExplorer.DragDropWidgetNVerify(draggableWidgets.INPUT_V2, 200, 600);
|
||||
|
||||
entityExplorer.SelectEntityByName("Button1");
|
||||
propPane.EnterJSContext("onClick", "{{Input1.set", true, false);
|
||||
agHelper.GetElementsNAssertTextPresence(locators._hints, "setDisabled()");
|
||||
});
|
||||
});
|
||||
|
|
@ -61,13 +61,13 @@ describe("Autocomplete using slash command and mustache tests", function () {
|
|||
cy.get(dynamicInputLocators.hints).should("exist");
|
||||
// validates all autocomplete functions on entering {{}} in onClick field
|
||||
cy.get(`${dynamicInputLocators.hints} li`)
|
||||
.eq(1)
|
||||
.eq(7)
|
||||
.should("have.text", "storeValue()");
|
||||
cy.get(`${dynamicInputLocators.hints} li`)
|
||||
.eq(2)
|
||||
.eq(8)
|
||||
.should("have.text", "showAlert()");
|
||||
cy.get(`${dynamicInputLocators.hints} li`)
|
||||
.eq(3)
|
||||
.eq(9)
|
||||
.should("have.text", "navigateTo()");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
import {
|
||||
PROPERTY_SELECTOR,
|
||||
WIDGET,
|
||||
getWidgetSelector,
|
||||
} from "../../../../locators/WidgetLocators";
|
||||
|
||||
import {
|
||||
entityExplorer,
|
||||
jsEditor,
|
||||
agHelper,
|
||||
locators,
|
||||
propPane,
|
||||
} from "../../../../support/Objects/ObjectsCore";
|
||||
|
||||
const setterMethodsToTest = [
|
||||
{
|
||||
name: "setVisibility",
|
||||
property: "isVisible",
|
||||
widget: WIDGET.INPUT_V2,
|
||||
actionBinding: "{{Input1.setVisibility(false)}}",
|
||||
valueBinding: "{{Input1.isVisible}}",
|
||||
expectedValue: "false",
|
||||
},
|
||||
{
|
||||
name: "setDisabled",
|
||||
property: "isDisabled",
|
||||
widget: WIDGET.INPUT_V2,
|
||||
actionBinding: "{{Input1.setDisabled(false)}}",
|
||||
valueBinding: "{{Input1.isDisabled}}",
|
||||
expectedValue: "false",
|
||||
},
|
||||
{
|
||||
name: "setRequired",
|
||||
property: "isRequired",
|
||||
widget: WIDGET.INPUT_V2,
|
||||
actionBinding: "{{Input1.setRequired(false)}}",
|
||||
valueBinding: "{{Input1.isRequired}}",
|
||||
expectedValue: "false",
|
||||
},
|
||||
{
|
||||
name: "setURL",
|
||||
property: "url",
|
||||
widget: WIDGET.AUDIO,
|
||||
actionBinding:
|
||||
"{{Audio1.setURL('https://www.youtube.com/watch?v=JGwWNGJdvx8')}}",
|
||||
valueBinding: "{{Audio1.url}}",
|
||||
expectedValue: "https://www.youtube.com/watch?v=JGwWNGJdvx8",
|
||||
},
|
||||
{
|
||||
name: "setPlaying",
|
||||
property: "playing",
|
||||
widget: WIDGET.AUDIO,
|
||||
actionBinding: "{{Audio1.setPlaying(true)}}",
|
||||
valueBinding: "{{Audio1.playing}}",
|
||||
expectedValue: "true",
|
||||
},
|
||||
{
|
||||
name: "setSelectedRowIndex",
|
||||
property: "selectedRowIndex",
|
||||
widget: WIDGET.TABLE,
|
||||
actionBinding: "{{Table1.setSelectedRowIndex(1)}}",
|
||||
valueBinding: "{{Table1.selectedRowIndex}}",
|
||||
expectedValue: "1",
|
||||
},
|
||||
{
|
||||
name: "setSelectedOption",
|
||||
property: "selectedOptionLabel",
|
||||
widget: WIDGET.SELECT,
|
||||
actionBinding: "{{Select1.setSelectedOption('BLUE')}}",
|
||||
valueBinding: "{{Select1.selectedOptionLabel}}",
|
||||
expectedValue: "Blue",
|
||||
},
|
||||
{
|
||||
name: "setProgress",
|
||||
property: "progress",
|
||||
widget: WIDGET.PROGRESS,
|
||||
actionBinding: "{{Progress1.setProgress(50)}}",
|
||||
valueBinding: "{{Progress1.progress}}",
|
||||
expectedValue: "50",
|
||||
},
|
||||
{
|
||||
name: "setText",
|
||||
property: "text",
|
||||
widget: WIDGET.TEXT,
|
||||
actionBinding: "{{Text1.setText('Hello World')}}",
|
||||
valueBinding: "{{Text1.text}}",
|
||||
expectedValue: "Hello World",
|
||||
},
|
||||
{
|
||||
name: "setValue",
|
||||
property: "text",
|
||||
widget: WIDGET.INPUT_V2,
|
||||
actionBinding: "{{Input1.setValue('Hello World')}}",
|
||||
valueBinding: "{{Input1.text}}",
|
||||
expectedValue: "Hello World",
|
||||
},
|
||||
{
|
||||
name: "setData",
|
||||
property: "tableData",
|
||||
widget: WIDGET.TABLE,
|
||||
actionBinding: "{{Table1.setData([{name: 'test'}])}}",
|
||||
valueBinding: "{{JSON.stringify(Table1.tableData)}}",
|
||||
expectedValue: '[{"name":"test"}]',
|
||||
},
|
||||
];
|
||||
|
||||
Object.values(setterMethodsToTest).forEach(
|
||||
(
|
||||
{ actionBinding, expectedValue, name, property, valueBinding, widget },
|
||||
index,
|
||||
) => {
|
||||
describe(`${index + 1}. ${name} method test`, () => {
|
||||
it(`1. DragDrop widget & Label/Text widgets and Verify the updated value`, () => {
|
||||
entityExplorer.DragDropWidgetNVerify(widget, 300, 200);
|
||||
entityExplorer.DragDropWidgetNVerify(WIDGET.BUTTON, 700, 200);
|
||||
|
||||
propPane.EnterJSContext(
|
||||
PROPERTY_SELECTOR.onClickFieldName,
|
||||
actionBinding,
|
||||
);
|
||||
|
||||
entityExplorer.DragDropWidgetNVerify(WIDGET.TEXT, 700, 400);
|
||||
|
||||
propPane.UpdatePropertyFieldValue(
|
||||
PROPERTY_SELECTOR.TextFieldName,
|
||||
valueBinding,
|
||||
);
|
||||
|
||||
agHelper.GetNClick(getWidgetSelector(WIDGET.BUTTON));
|
||||
|
||||
agHelper.GetText(getWidgetSelector(WIDGET.TEXT)).then(($label) => {
|
||||
expect($label).to.eq(expectedValue);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach("Delete all the widgets on canvas", () => {
|
||||
agHelper.GetNClick(locators._widgetInCanvas(widget));
|
||||
agHelper.PressDelete();
|
||||
|
||||
agHelper.GetNClick(getWidgetSelector(WIDGET.BUTTON));
|
||||
agHelper.AssertContains("is not defined"); // Since widget is removed & Button is still holding its reference
|
||||
agHelper.PressDelete();
|
||||
|
||||
agHelper.GetNClick(getWidgetSelector(WIDGET.TEXT)).click();
|
||||
agHelper.GetNClick(propPane._deleteWidget);
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
describe("Linting warning for setter methods", function () {
|
||||
it("Lint error when setter is used in a data field", function () {
|
||||
entityExplorer.DragDropWidgetNVerify(WIDGET.BUTTON, 200, 200);
|
||||
agHelper.GetNClick(getWidgetSelector(WIDGET.BUTTON));
|
||||
propPane.TypeTextIntoField("Label", "{{Button1.setLabel('Hello')}}");
|
||||
|
||||
//Mouse hover to exact warning message
|
||||
agHelper.HoverElement(locators._lintErrorElement);
|
||||
agHelper.AssertContains("Data fields cannot execute async code");
|
||||
|
||||
//Create a JS object
|
||||
jsEditor.CreateJSObject(
|
||||
`export default {
|
||||
myFun1: () => {
|
||||
Button1.setLabel('Hello');
|
||||
},
|
||||
}`,
|
||||
{
|
||||
paste: true,
|
||||
completeReplace: true,
|
||||
toRun: false,
|
||||
shouldCreateNewJSObj: true,
|
||||
prettify: false,
|
||||
},
|
||||
);
|
||||
|
||||
//Add myFun1 to onClick
|
||||
entityExplorer.SelectEntityByName("Button1");
|
||||
propPane.TypeTextIntoField("Label", "{{JSObject1.myFun1()}}");
|
||||
|
||||
agHelper.AssertContains(
|
||||
"Found an action invocation during evaluation. Data fields cannot execute actions.",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -35,6 +35,7 @@ export const WIDGET = {
|
|||
RANGE_SLIDER: "rangesliderwidget",
|
||||
IFRAME: "iframewidget",
|
||||
DIVIDER: "dividerwidget",
|
||||
PROGRESS: "progresswidget",
|
||||
MODAL: "modalwidget",
|
||||
FORM: "formwidget",
|
||||
ICONBUTTON: "iconbuttonwidget",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
|
||||
import set from "lodash/set";
|
||||
import type { DataTree } from "entities/DataTree/dataTreeFactory";
|
||||
import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory";
|
||||
import type { EvalContext } from "workers/Evaluation/evaluate";
|
||||
import type { EvaluationVersion } from "@appsmith/api/ApplicationApi";
|
||||
import { addFn } from "workers/Evaluation/fns/utils/fnGuard";
|
||||
|
|
@ -11,6 +11,8 @@ import {
|
|||
} from "@appsmith/workers/Evaluation/fns";
|
||||
import { getEntityForEvalContext } from "workers/Evaluation/getEntityForContext";
|
||||
import { klona } from "klona/full";
|
||||
import { isEmpty } from "lodash";
|
||||
import setters from "workers/Evaluation/setters";
|
||||
declare global {
|
||||
/** All identifiers added to the worker global scope should also
|
||||
* be included in the DEDICATED_WORKER_GLOBAL_SCOPE_IDENTIFIERS in
|
||||
|
|
@ -38,8 +40,10 @@ export const addDataTreeToContext = (args: {
|
|||
dataTree: Readonly<DataTree>;
|
||||
removeEntityFunctions?: boolean;
|
||||
isTriggerBased: boolean;
|
||||
configTree: ConfigTree;
|
||||
}) => {
|
||||
const {
|
||||
configTree,
|
||||
dataTree,
|
||||
EVAL_CONTEXT,
|
||||
isTriggerBased,
|
||||
|
|
@ -48,15 +52,39 @@ export const addDataTreeToContext = (args: {
|
|||
const dataTreeEntries = Object.entries(dataTree);
|
||||
const entityFunctionCollection: Record<string, Record<string, Function>> = {};
|
||||
|
||||
if (isTriggerBased && !removeEntityFunctions) setters.clear();
|
||||
|
||||
for (const [entityName, entity] of dataTreeEntries) {
|
||||
EVAL_CONTEXT[entityName] = getEntityForEvalContext(entity, entityName);
|
||||
if (!removeEntityFunctions && !isTriggerBased) continue;
|
||||
|
||||
// when we evaluate data field and removeEntityFunctions is true then we skip adding entity function to evalContext
|
||||
const skipEntityFunctions = !removeEntityFunctions && !isTriggerBased;
|
||||
|
||||
if (skipEntityFunctions) continue;
|
||||
|
||||
for (const entityFn of entityFns) {
|
||||
if (!entityFn.qualifier(entity)) continue;
|
||||
const func = entityFn.fn(entity, entityName);
|
||||
const fullPath = `${entityFn.path || `${entityName}.${entityFn.name}`}`;
|
||||
set(entityFunctionCollection, fullPath, func);
|
||||
}
|
||||
|
||||
// Don't add entity function ( setter method ) to evalContext if removeEntityFunctions is true
|
||||
if (removeEntityFunctions) continue;
|
||||
|
||||
const entityConfig = configTree[entityName];
|
||||
const entityMethodMap = setters.getEntitySettersFromConfig(
|
||||
entityConfig,
|
||||
entityName,
|
||||
entity,
|
||||
);
|
||||
|
||||
if (isEmpty(entityMethodMap)) continue;
|
||||
EVAL_CONTEXT[entityName] = Object.assign(
|
||||
{},
|
||||
dataTree[entityName],
|
||||
entityMethodMap,
|
||||
);
|
||||
}
|
||||
|
||||
if (removeEntityFunctions)
|
||||
|
|
@ -71,7 +99,11 @@ export const addDataTreeToContext = (args: {
|
|||
for (const [entityName, funcObj] of Object.entries(
|
||||
entityFunctionCollection,
|
||||
)) {
|
||||
EVAL_CONTEXT[entityName] = Object.assign({}, dataTree[entityName], funcObj);
|
||||
EVAL_CONTEXT[entityName] = Object.assign(
|
||||
{},
|
||||
EVAL_CONTEXT[entityName],
|
||||
funcObj,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -81,7 +113,10 @@ export const addPlatformFunctionsToEvalContext = (context: any) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const getAllAsyncFunctions = (dataTree: DataTree) => {
|
||||
export const getAllAsyncFunctions = (
|
||||
dataTree: DataTree,
|
||||
configTree: ConfigTree,
|
||||
) => {
|
||||
const asyncFunctionNameMap: Record<string, true> = {};
|
||||
const dataTreeEntries = Object.entries(dataTree);
|
||||
for (const [entityName, entity] of dataTreeEntries) {
|
||||
|
|
@ -90,6 +125,19 @@ export const getAllAsyncFunctions = (dataTree: DataTree) => {
|
|||
const fullPath = `${entityFn.path || `${entityName}.${entityFn.name}`}`;
|
||||
asyncFunctionNameMap[fullPath] = true;
|
||||
}
|
||||
|
||||
const entityConfig = configTree[entityName];
|
||||
const entityMethodMap = setters.getEntitySettersFromConfig(
|
||||
entityConfig,
|
||||
entityName,
|
||||
entity,
|
||||
);
|
||||
|
||||
if (isEmpty(entityMethodMap)) continue;
|
||||
|
||||
for (const methodName of Object.keys(entityMethodMap)) {
|
||||
asyncFunctionNameMap[`${entityName}.${methodName}`] = true;
|
||||
}
|
||||
}
|
||||
for (const platformFn of getPlatformFunctions(self.$cloudHosting)) {
|
||||
asyncFunctionNameMap[platformFn.name] = true;
|
||||
|
|
|
|||
|
|
@ -783,6 +783,8 @@ export const overrideWidgetProperties = (params: {
|
|||
evalMetaUpdates: EvalMetaUpdates;
|
||||
fullPropertyPath: string;
|
||||
isNewWidget: boolean;
|
||||
shouldUpdateGlobalContext?: boolean;
|
||||
overriddenProperties?: string[];
|
||||
}) => {
|
||||
const {
|
||||
configTree,
|
||||
|
|
@ -791,7 +793,9 @@ export const overrideWidgetProperties = (params: {
|
|||
evalMetaUpdates,
|
||||
fullPropertyPath,
|
||||
isNewWidget,
|
||||
overriddenProperties,
|
||||
propertyPath,
|
||||
shouldUpdateGlobalContext,
|
||||
value,
|
||||
} = params;
|
||||
const clonedValue = klona(value);
|
||||
|
|
@ -813,9 +817,14 @@ export const overrideWidgetProperties = (params: {
|
|||
if (pathsNotToOverride.includes(overriddenPropertyPath)) return;
|
||||
_.set(
|
||||
currentTree,
|
||||
[entity.widgetName, ...overriddenPropertyPathArray],
|
||||
[entityName, ...overriddenPropertyPathArray],
|
||||
clonedValue,
|
||||
);
|
||||
|
||||
if (shouldUpdateGlobalContext) {
|
||||
_.set(self, [entityName, ...overriddenPropertyPathArray], clonedValue);
|
||||
}
|
||||
overriddenProperties?.push(overriddenPropertyPath);
|
||||
// evalMetaUpdates has all updates from property which overrides meta values.
|
||||
if (
|
||||
propertyPath.split(".")[0] !== "meta" &&
|
||||
|
|
@ -844,10 +853,14 @@ export const overrideWidgetProperties = (params: {
|
|||
const propertyPathArray = propertyPath.split(".");
|
||||
_.set(
|
||||
currentTree,
|
||||
[entity.widgetName, ...propertyPathArray],
|
||||
[entityName, ...propertyPathArray],
|
||||
clonedDefaultValue,
|
||||
);
|
||||
|
||||
if (shouldUpdateGlobalContext) {
|
||||
_.set(self, [entityName, ...propertyPathArray], clonedDefaultValue);
|
||||
}
|
||||
|
||||
return {
|
||||
overwriteParsedValue: true,
|
||||
newValue: clonedDefaultValue,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { zIndexLayers } from "constants/CanvasEditorConstants";
|
|||
import { objectCollapseAnalytics, textSelectAnalytics } from "./Analytics";
|
||||
import { Divider } from "design-system";
|
||||
import { useSelector } from "react-redux";
|
||||
import { getDataTree } from "selectors/dataTreeSelectors";
|
||||
import { getConfigTree, getDataTree } from "selectors/dataTreeSelectors";
|
||||
import { filterInternalProperties } from "utils/FilterInternalProperties";
|
||||
import { getJSCollections } from "selectors/entitiesSelector";
|
||||
|
||||
|
|
@ -54,6 +54,7 @@ export function PeekOverlayPopUpContent(
|
|||
const CONTAINER_MAX_HEIGHT_PX = 252;
|
||||
const dataWrapperRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
const dataTree = useSelector(getDataTree);
|
||||
const configTree = useSelector(getConfigTree);
|
||||
const jsActions = useSelector(getJSCollections);
|
||||
|
||||
const filteredData = filterInternalProperties(
|
||||
|
|
@ -61,6 +62,7 @@ export function PeekOverlayPopUpContent(
|
|||
dataTree[props.objectName],
|
||||
jsActions,
|
||||
dataTree,
|
||||
configTree,
|
||||
);
|
||||
|
||||
// Because getPropertyData can return a function
|
||||
|
|
|
|||
|
|
@ -75,3 +75,13 @@ export type AppTheme = {
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type SetterConfig = {
|
||||
__setters: {
|
||||
[key: string]: {
|
||||
path: string;
|
||||
type: string;
|
||||
disabled?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ export interface WidgetEntityConfig
|
|||
WidgetConfig {
|
||||
defaultMetaProps: Array<string>;
|
||||
type: string;
|
||||
__setters?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface AppsmithEntity extends Omit<AppDataState, "store"> {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import type { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import { generateDataTreeWidget } from "entities/DataTree/dataTreeWidget";
|
||||
import {
|
||||
generateDataTreeWidget,
|
||||
getSetterConfig,
|
||||
} from "entities/DataTree/dataTreeWidget";
|
||||
import {
|
||||
ENTITY_TYPE,
|
||||
EvaluationSubstitutionType,
|
||||
|
|
@ -305,4 +308,310 @@ describe("generateDataTreeWidget", () => {
|
|||
expect(result.unEvalEntity).toStrictEqual(expectedData);
|
||||
expect(result.configEntity).toStrictEqual(expectedConfig);
|
||||
});
|
||||
|
||||
it("generates setterConfig with the dynamic data", () => {
|
||||
// Input widget
|
||||
const inputWidget: FlattenedWidgetProps = {
|
||||
bottomRow: 0,
|
||||
isLoading: false,
|
||||
leftColumn: 0,
|
||||
parentColumnSpace: 0,
|
||||
parentRowSpace: 0,
|
||||
renderMode: RenderModes.CANVAS,
|
||||
rightColumn: 0,
|
||||
topRow: 0,
|
||||
type: "INPUT_WIDGET_V2",
|
||||
version: 0,
|
||||
widgetId: "123",
|
||||
widgetName: "Input1",
|
||||
defaultText: "",
|
||||
deepObj: {
|
||||
level1: {
|
||||
value: 10,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const inputSetterConfig: Record<string, any> = {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultText",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const expectedInputData = {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "Input1.isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "Input1.isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "Input1.isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "Input1.defaultText",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const inputResult = getSetterConfig(inputSetterConfig, inputWidget);
|
||||
|
||||
expect(inputResult).toStrictEqual(expectedInputData);
|
||||
|
||||
//Json form widget
|
||||
|
||||
const jsonFormWidget: FlattenedWidgetProps = {
|
||||
bottomRow: 0,
|
||||
isLoading: false,
|
||||
leftColumn: 0,
|
||||
parentColumnSpace: 0,
|
||||
parentRowSpace: 0,
|
||||
renderMode: RenderModes.CANVAS,
|
||||
rightColumn: 0,
|
||||
topRow: 0,
|
||||
type: "FORM_WIDGET",
|
||||
version: 0,
|
||||
widgetId: "123",
|
||||
widgetName: "Form1",
|
||||
defaultText: "",
|
||||
deepObj: {
|
||||
level1: {
|
||||
value: 10,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const jsonFormSetterConfig: Record<string, any> = {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setData: {
|
||||
path: "sourceData",
|
||||
type: "object",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const expectedJsonFormData = {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "Form1.isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setData: {
|
||||
path: "Form1.sourceData",
|
||||
type: "object",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const jsonFormResult = getSetterConfig(
|
||||
jsonFormSetterConfig,
|
||||
jsonFormWidget,
|
||||
);
|
||||
|
||||
expect(jsonFormResult).toStrictEqual(expectedJsonFormData);
|
||||
|
||||
// Table widget
|
||||
const tableWidget: FlattenedWidgetProps = {
|
||||
bottomRow: 0,
|
||||
isLoading: false,
|
||||
leftColumn: 0,
|
||||
parentColumnSpace: 0,
|
||||
parentRowSpace: 0,
|
||||
renderMode: RenderModes.CANVAS,
|
||||
rightColumn: 0,
|
||||
topRow: 0,
|
||||
type: "TABLE_WIDGET",
|
||||
version: 0,
|
||||
widgetId: "123",
|
||||
widgetName: "Table1",
|
||||
defaultText: "",
|
||||
deepObj: {
|
||||
level1: {
|
||||
value: 10,
|
||||
},
|
||||
},
|
||||
primaryColumns: {
|
||||
step: {
|
||||
index: 0,
|
||||
width: 150,
|
||||
id: "step",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "text",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
isDerived: false,
|
||||
label: "step",
|
||||
computedValue:
|
||||
"{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}",
|
||||
},
|
||||
task: {
|
||||
index: 1,
|
||||
width: 150,
|
||||
id: "task",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "text",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
isDerived: false,
|
||||
label: "task",
|
||||
computedValue:
|
||||
"{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}",
|
||||
},
|
||||
status: {
|
||||
index: 2,
|
||||
width: 150,
|
||||
id: "status",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "text",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
isDerived: false,
|
||||
label: "status",
|
||||
computedValue:
|
||||
"{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}",
|
||||
},
|
||||
action: {
|
||||
index: 3,
|
||||
width: 150,
|
||||
id: "action",
|
||||
horizontalAlignment: "LEFT",
|
||||
verticalAlignment: "CENTER",
|
||||
columnType: "button",
|
||||
textSize: "PARAGRAPH",
|
||||
enableFilter: true,
|
||||
enableSort: true,
|
||||
isVisible: true,
|
||||
isCellVisible: true,
|
||||
isDisabled: false,
|
||||
isDerived: false,
|
||||
label: "action",
|
||||
onClick:
|
||||
"{{currentRow.step === '#1' ? showAlert('Done', 'success') : currentRow.step === '#2' ? navigateTo('https://docs.appsmith.com/core-concepts/connecting-to-data-sources/querying-a-database',undefined,'NEW_WINDOW') : navigateTo('https://docs.appsmith.com/core-concepts/displaying-data-read/display-data-tables',undefined,'NEW_WINDOW')}}",
|
||||
computedValue:
|
||||
"{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.action))}}",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const tableSetterConfig: Record<string, any> = {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "string",
|
||||
},
|
||||
setSelectedRowIndex: {
|
||||
path: "defaultSelectedRowIndex",
|
||||
type: "number",
|
||||
disabled: "return options.entity.multiRowSelection",
|
||||
},
|
||||
setSelectedRowIndices: {
|
||||
path: "defaultSelectedRowIndices",
|
||||
type: "array",
|
||||
disabled: "return !options.entity.multiRowSelection",
|
||||
},
|
||||
setData: {
|
||||
path: "tableData",
|
||||
type: "object",
|
||||
},
|
||||
},
|
||||
text: {
|
||||
__setters: {
|
||||
setIsRequired: {
|
||||
path: "primaryColumns.$columnId.isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
button: {
|
||||
__setters: {
|
||||
setIsRequired: {
|
||||
path: "primaryColumns.$columnId.isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
pathToSetters: [
|
||||
{ path: "primaryColumns.$columnId", property: "columnType" },
|
||||
],
|
||||
};
|
||||
|
||||
const expectedTableData = {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "Table1.isVisible",
|
||||
type: "string",
|
||||
},
|
||||
setSelectedRowIndex: {
|
||||
path: "Table1.defaultSelectedRowIndex",
|
||||
type: "number",
|
||||
disabled: "return options.entity.multiRowSelection",
|
||||
},
|
||||
setSelectedRowIndices: {
|
||||
path: "Table1.defaultSelectedRowIndices",
|
||||
type: "array",
|
||||
disabled: "return !options.entity.multiRowSelection",
|
||||
},
|
||||
setData: {
|
||||
path: "Table1.tableData",
|
||||
type: "object",
|
||||
},
|
||||
"primaryColumns.action.setIsRequired": {
|
||||
path: "Table1.primaryColumns.action.isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
"primaryColumns.status.setIsRequired": {
|
||||
path: "Table1.primaryColumns.status.isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
"primaryColumns.step.setIsRequired": {
|
||||
path: "Table1.primaryColumns.step.isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
"primaryColumns.task.setIsRequired": {
|
||||
path: "Table1.primaryColumns.task.isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const tableResult = getSetterConfig(tableSetterConfig, tableWidget);
|
||||
|
||||
expect(tableResult).toStrictEqual(expectedTableData);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { getAllPathsFromPropertyConfig } from "entities/Widget/utils";
|
||||
import _, { isEmpty } from "lodash";
|
||||
import _, { get, isEmpty } from "lodash";
|
||||
import memoize from "micro-memoize";
|
||||
import type { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import type { DynamicPath } from "utils/DynamicBindingUtils";
|
||||
|
|
@ -14,6 +14,140 @@ import type {
|
|||
import { OverridingPropertyType } from "./types";
|
||||
|
||||
import { setOverridingProperty } from "./utils";
|
||||
import { error } from "loglevel";
|
||||
|
||||
/**
|
||||
*
|
||||
* Example of setterConfig
|
||||
*
|
||||
* {
|
||||
WIDGET: {
|
||||
TABLE_WIDGET_V2: {
|
||||
__setters: {
|
||||
setIsRequired: {
|
||||
path: "isRequired"
|
||||
},
|
||||
},
|
||||
"text": {
|
||||
__setters:{
|
||||
setIsRequired: {
|
||||
path: "primaryColumns.$columnId.isRequired"
|
||||
}
|
||||
}
|
||||
}
|
||||
pathToSetters: [{ path: "primaryColumns.$columnId", property: "columnType" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
columnId = action
|
||||
|
||||
Expected output
|
||||
|
||||
{
|
||||
Table2: {
|
||||
isRequired: true,
|
||||
__setters: {
|
||||
setIsRequired: {
|
||||
path: "Table2.isRequired"
|
||||
},
|
||||
"primaryColumns.action.setIsRequired": {
|
||||
path: "Table2.primaryColumns.action.isRequired"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
export function getSetterConfig(
|
||||
setterConfig: Record<string, any>,
|
||||
widget: FlattenedWidgetProps,
|
||||
) {
|
||||
const modifiedSetterConfig: Record<string, any> = {};
|
||||
|
||||
try {
|
||||
if (setterConfig.__setters) {
|
||||
modifiedSetterConfig.__setters = {};
|
||||
for (const setterMethodName of Object.keys(setterConfig.__setters)) {
|
||||
const staticConfigSetter = setterConfig.__setters[setterMethodName];
|
||||
|
||||
modifiedSetterConfig.__setters[setterMethodName] = {
|
||||
path: `${widget.widgetName}.${staticConfigSetter.path}`,
|
||||
type: staticConfigSetter.type,
|
||||
};
|
||||
|
||||
if (staticConfigSetter.disabled) {
|
||||
modifiedSetterConfig.__setters[setterMethodName].disabled =
|
||||
staticConfigSetter.disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!setterConfig.pathToSetters || !setterConfig.pathToSetters.length)
|
||||
return modifiedSetterConfig;
|
||||
|
||||
const pathToSetters = setterConfig.pathToSetters;
|
||||
|
||||
//pathToSetters = [{ path: "primaryColumns.$columnId", property: "columnType" }]
|
||||
for (const { path, property } of pathToSetters) {
|
||||
const pathArray = path.split(".");
|
||||
const placeHolder = pathArray[pathArray.length - 1];
|
||||
|
||||
if (placeHolder[0] !== "$") continue;
|
||||
|
||||
//pathToParentObj = primaryColumns
|
||||
const pathToParentObj = pathArray.slice(0, -1).join(".");
|
||||
const accessors = Object.keys(get(widget, pathToParentObj));
|
||||
|
||||
//accessors = action, step, status, task
|
||||
for (const accesskey of accessors) {
|
||||
const fullPath = pathToParentObj + "." + accesskey;
|
||||
const accessorObject = get(widget, fullPath);
|
||||
|
||||
//propertyType = text, button etc
|
||||
const propertyType = accessorObject[property];
|
||||
if (!propertyType) continue;
|
||||
|
||||
// "text": {
|
||||
// __setters:{
|
||||
// setIsRequired: {
|
||||
// path: "primaryColumns.$columnId.isRequired"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
const accessorSetterConfig = setterConfig[propertyType];
|
||||
if (!accessorSetterConfig) continue;
|
||||
|
||||
const accessorSettersMap = accessorSetterConfig.__setters;
|
||||
if (!accessorSettersMap) continue;
|
||||
|
||||
const entries = Object.entries(accessorSettersMap) as [
|
||||
string,
|
||||
Record<string, unknown>,
|
||||
][];
|
||||
|
||||
for (const [setterName, setterBody] of entries) {
|
||||
//path = primaryColumns.action.isRequired
|
||||
const path = (setterBody as any).path.replace(placeHolder, accesskey);
|
||||
const setterPathArray = path.split(".");
|
||||
setterPathArray.pop();
|
||||
setterPathArray.push(setterName);
|
||||
|
||||
//setterPath = primaryColumns.action.setIsRequired
|
||||
const setterPath = setterPathArray.join(".");
|
||||
modifiedSetterConfig.__setters[setterPath] = {
|
||||
path: `${widget.widgetName}.${path}`, //Table2.primaryColumns.action.isRequired
|
||||
type: setterBody.type,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
error("Error while generating setter config", e);
|
||||
}
|
||||
|
||||
return modifiedSetterConfig;
|
||||
}
|
||||
|
||||
// We are splitting generateDataTreeWidget into two parts to memoize better as the widget doesn't change very often.
|
||||
// Widget changes only when dynamicBindingPathList changes.
|
||||
|
|
@ -139,6 +273,11 @@ const generateDataTreeWidgetWithoutMeta = (
|
|||
"type",
|
||||
];
|
||||
|
||||
const setterConfig = getSetterConfig(
|
||||
WidgetFactory.getWidgetSetterConfig(widget.type),
|
||||
widget,
|
||||
);
|
||||
|
||||
const dataTreeWidgetWithoutMetaProps = _.merge(
|
||||
{
|
||||
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
||||
|
|
@ -181,6 +320,7 @@ const generateDataTreeWidgetWithoutMeta = (
|
|||
overridingPropertyPaths,
|
||||
type: widget.type,
|
||||
...dynamicPathsList,
|
||||
...setterConfig,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
@ -208,6 +348,7 @@ export const generateDataTreeWidget = (
|
|||
|
||||
// overridingMetaProps maps properties that can be overriden by either default values or meta changes to initial values.
|
||||
// initial value is set to metaProps value or defaultMetaProps value.
|
||||
|
||||
Object.entries(defaultMetaProps).forEach(([key, value]) => {
|
||||
if (overridingMetaPropsMap[key]) {
|
||||
overridingMetaProps[key] =
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export interface ActionEntity {
|
|||
datasourceUrl: string;
|
||||
}
|
||||
|
||||
export interface ActionEntityConfig {
|
||||
export interface ActionEntityConfig extends EntityConfig {
|
||||
dynamicBindingPathList: DynamicPath[];
|
||||
bindingPaths: Record<string, EvaluationSubstitutionType>;
|
||||
reactivePaths: Record<string, EvaluationSubstitutionType>;
|
||||
|
|
@ -60,7 +60,7 @@ export interface MetaArgs {
|
|||
confirmBeforeExecute: boolean;
|
||||
}
|
||||
|
||||
export interface JSActionEntityConfig {
|
||||
export interface JSActionEntityConfig extends EntityConfig {
|
||||
meta: Record<string, MetaArgs>;
|
||||
dynamicBindingPathList: DynamicPath[];
|
||||
bindingPaths: Record<string, EvaluationSubstitutionType>;
|
||||
|
|
@ -109,7 +109,7 @@ export type PropertyOverrideDependency = Record<
|
|||
Partial<overrideDependency>
|
||||
>;
|
||||
|
||||
export type WidgetConfig = {
|
||||
export interface WidgetConfig extends EntityConfig {
|
||||
bindingPaths: Record<string, EvaluationSubstitutionType>;
|
||||
reactivePaths: Record<string, EvaluationSubstitutionType>;
|
||||
triggerPaths: Record<string, boolean>;
|
||||
|
|
@ -119,4 +119,12 @@ export type WidgetConfig = {
|
|||
propertyOverrideDependency: PropertyOverrideDependency;
|
||||
overridingPropertyPaths: OverridingPropertyPaths;
|
||||
privateWidgets: PrivateWidgets;
|
||||
};
|
||||
}
|
||||
|
||||
export interface EntityConfig {
|
||||
__setters?: Record<string, unknown>;
|
||||
bindingPaths?: Record<string, EvaluationSubstitutionType>;
|
||||
reactivePaths?: Record<string, EvaluationSubstitutionType>;
|
||||
validationPaths?: Record<string, ValidationConfig>;
|
||||
dynamicBindingPathList?: DynamicPath[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ export function EntityProperties() {
|
|||
break;
|
||||
case ENTITY_TYPE.ACTION:
|
||||
config = (entityDefinitions.ACTION as any)(entity as any);
|
||||
|
||||
if (config) {
|
||||
entityProperties = Object.keys(config)
|
||||
.filter((k) => k.indexOf("!") === -1)
|
||||
|
|
@ -200,9 +201,12 @@ export function EntityProperties() {
|
|||
}
|
||||
|
||||
if (isFunction(config)) config = config(entity);
|
||||
const settersConfig =
|
||||
WidgetFactory.getWidgetSetterConfig(type)?.__setters;
|
||||
|
||||
entityProperties = Object.keys(config)
|
||||
.filter((k) => k.indexOf("!") === -1)
|
||||
.filter((k) => settersConfig && !settersConfig[k])
|
||||
.map((widgetProperty) => {
|
||||
return {
|
||||
propertyName: widgetProperty,
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export const CUSTOM_LINT_ERRORS: Record<
|
|||
entity: unknown,
|
||||
isJsObject: boolean,
|
||||
) =>
|
||||
isEntityFunction(entity, propertyName)
|
||||
isEntityFunction(entity, propertyName, entityName)
|
||||
? asyncActionInSyncFieldLintMessage(isJsObject)
|
||||
: `"${propertyName}" doesn't exist in ${entityName}`,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,24 @@
|
|||
import type { DataTree } from "entities/DataTree/dataTreeFactory";
|
||||
import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory";
|
||||
import { isEmpty } from "lodash";
|
||||
import type { EvalContext } from "workers/Evaluation/evaluate";
|
||||
import getEvaluationContext from "./utils/getEvaluationContext";
|
||||
import { getEvaluationContext } from "./utils/getEvaluationContext";
|
||||
|
||||
class GlobalData {
|
||||
globalDataWithFunctions: EvalContext = {};
|
||||
globalDataWithoutFunctions: EvalContext = {};
|
||||
unevalTree: DataTree = {};
|
||||
configTree: ConfigTree = {};
|
||||
cloudHosting = false;
|
||||
|
||||
initialize(unevalTree: DataTree, cloudHosting: boolean) {
|
||||
initialize(
|
||||
unevalTree: DataTree,
|
||||
configTree: ConfigTree,
|
||||
cloudHosting: boolean,
|
||||
) {
|
||||
this.globalDataWithFunctions = {};
|
||||
this.globalDataWithoutFunctions = {};
|
||||
this.unevalTree = unevalTree;
|
||||
this.configTree = configTree;
|
||||
this.cloudHosting = cloudHosting;
|
||||
}
|
||||
|
||||
|
|
@ -22,6 +28,7 @@ class GlobalData {
|
|||
if (isEmpty(this.globalDataWithFunctions)) {
|
||||
this.globalDataWithFunctions = getEvaluationContext(
|
||||
this.unevalTree,
|
||||
this.configTree,
|
||||
this.cloudHosting,
|
||||
{
|
||||
withFunctions: true,
|
||||
|
|
@ -33,6 +40,7 @@ class GlobalData {
|
|||
if (isEmpty(this.globalDataWithoutFunctions)) {
|
||||
this.globalDataWithoutFunctions = getEvaluationContext(
|
||||
this.unevalTree,
|
||||
this.configTree,
|
||||
this.cloudHosting,
|
||||
{
|
||||
withFunctions: false,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import lintTriggerPath from "./utils/lintTriggerPath";
|
|||
import lintJSObjectBody from "./utils/lintJSObjectBody";
|
||||
import sortLintingPathsByType from "./utils/sortLintingPathsByType";
|
||||
import lintJSObjectProperty from "./utils/lintJSObjectProperty";
|
||||
import setters from "workers/Evaluation/setters";
|
||||
import type {
|
||||
getLintErrorsFromTreeProps,
|
||||
getLintErrorsFromTreeResponse,
|
||||
|
|
@ -23,7 +24,10 @@ export function getLintErrorsFromTree({
|
|||
}: getLintErrorsFromTreeProps): getLintErrorsFromTreeResponse {
|
||||
const lintTreeErrors: LintErrorsStore = {};
|
||||
const lintedJSPaths = new Set<string>();
|
||||
globalData.initialize(unEvalTree, cloudHosting);
|
||||
|
||||
setters.init(configTree, unEvalTree);
|
||||
globalData.initialize(unEvalTree, configTree, cloudHosting);
|
||||
|
||||
const { bindingPaths, jsObjectPaths, triggerPaths } = sortLintingPathsByType(
|
||||
pathsToLint,
|
||||
unEvalTree,
|
||||
|
|
|
|||
|
|
@ -1,22 +1,25 @@
|
|||
import type { DataTree } from "entities/DataTree/dataTreeFactory";
|
||||
import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory";
|
||||
import { createEvaluationContext } from "workers/Evaluation/evaluate";
|
||||
import { getActionTriggerFunctionNames } from "@appsmith/workers/Evaluation/fns";
|
||||
|
||||
export default function getEvaluationContext(
|
||||
export function getEvaluationContext(
|
||||
unevalTree: DataTree,
|
||||
configTree: ConfigTree,
|
||||
cloudHosting: boolean,
|
||||
options: { withFunctions: boolean },
|
||||
) {
|
||||
if (!options.withFunctions)
|
||||
return createEvaluationContext({
|
||||
dataTree: unevalTree,
|
||||
configTree,
|
||||
isTriggerBased: false,
|
||||
removeEntityFunctions: true,
|
||||
});
|
||||
|
||||
const evalContext = createEvaluationContext({
|
||||
dataTree: unevalTree,
|
||||
isTriggerBased: false,
|
||||
configTree,
|
||||
isTriggerBased: true,
|
||||
removeEntityFunctions: false,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
import type { DataTreeEntity } from "entities/DataTree/dataTreeFactory";
|
||||
import { isDataTreeEntity } from "@appsmith/workers/Evaluation/evaluationUtils";
|
||||
import { entityFns } from "@appsmith/workers/Evaluation/fns";
|
||||
import setters from "workers/Evaluation/setters";
|
||||
|
||||
export default function isEntityFunction(
|
||||
entity: unknown,
|
||||
propertyName: string,
|
||||
entityName: string,
|
||||
) {
|
||||
if (!isDataTreeEntity(entity)) return false;
|
||||
|
||||
if (setters.has(entityName, propertyName)) return true;
|
||||
|
||||
return entityFns.find((entityFn) => {
|
||||
const entityFnpropertyName = entityFn.path
|
||||
? entityFn.path.split(".")[1]
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ export function* handleEvalWorkerMessage(message: TMessage<any>) {
|
|||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case MAIN_THREAD_ACTION.PROCESS_JS_VAR_MUTATION_EVENTS: {
|
||||
const jsVarMutatedEvents: JSVarMutatedEvents = data;
|
||||
yield call(logJSVarMutationEvent, jsVarMutatedEvents);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,25 @@
|
|||
import type {
|
||||
ConfigTree,
|
||||
DataTree,
|
||||
WidgetEntity,
|
||||
WidgetEntityConfig,
|
||||
} from "entities/DataTree/dataTreeFactory";
|
||||
import type { EntityDefinitionsOptions } from "@appsmith/utils/autocomplete/EntityDefinitions";
|
||||
import type { DataTree, WidgetEntity } from "entities/DataTree/dataTreeFactory";
|
||||
import { isFunction } from "lodash";
|
||||
import type { Def } from "tern";
|
||||
import WidgetFactory from "utils/WidgetFactory";
|
||||
import { addSettersToDefinitions } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
|
||||
export const getWidgetChildrenPeekData = (
|
||||
widgetName: string,
|
||||
widgetType: string,
|
||||
dataTree: DataTree,
|
||||
configTree: ConfigTree,
|
||||
) => {
|
||||
const peekData: Record<string, unknown> = {};
|
||||
const dataTreeWidget: WidgetEntity = dataTree[widgetName] as WidgetEntity;
|
||||
const widgetConfig = configTree[widgetName];
|
||||
|
||||
if (widgetType !== "FORM_WIDGET" && dataTreeWidget) {
|
||||
const type: Exclude<
|
||||
EntityDefinitionsOptions,
|
||||
|
|
@ -21,12 +31,32 @@ export const getWidgetChildrenPeekData = (
|
|||
let config: any = WidgetFactory.getAutocompleteDefinitions(type);
|
||||
if (config) {
|
||||
if (isFunction(config)) config = config(dataTreeWidget);
|
||||
|
||||
// Need to add this in order to add the setters to the definitions which will appear in the peekOverlay
|
||||
addSettersToDefinitions(
|
||||
config as Def,
|
||||
dataTreeWidget,
|
||||
configTree[widgetName] as WidgetEntityConfig,
|
||||
);
|
||||
|
||||
const widgetProps = Object.keys(config).filter(
|
||||
(k) => k.indexOf("!") === -1,
|
||||
);
|
||||
|
||||
widgetProps.forEach((prop) => {
|
||||
const data = dataTreeWidget[prop];
|
||||
|
||||
let setterNames: string[] = [];
|
||||
|
||||
if (widgetConfig.__setters) {
|
||||
setterNames = Object.keys(widgetConfig.__setters);
|
||||
}
|
||||
if (setterNames.includes(prop)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
peekData[prop] = function () {}; // tern inference required here
|
||||
} else {
|
||||
peekData[prop] = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { getActionChildrenPeekData } from "./Action";
|
||||
import type {
|
||||
ConfigTree,
|
||||
DataTree,
|
||||
DataTreeEntity,
|
||||
} from "entities/DataTree/dataTreeFactory";
|
||||
|
|
@ -21,6 +22,7 @@ export const filterInternalProperties = (
|
|||
dataTreeEntity: DataTreeEntity,
|
||||
jsActions: JSCollectionDataState,
|
||||
dataTree: DataTree,
|
||||
configTree: ConfigTree,
|
||||
) => {
|
||||
if (!dataTreeEntity) return;
|
||||
if (isActionEntity(dataTreeEntity)) {
|
||||
|
|
@ -35,8 +37,12 @@ export const filterInternalProperties = (
|
|||
? getJsActionPeekData(jsAction, dataTree)?.peekData
|
||||
: dataTreeEntity;
|
||||
} else if (isWidgetEntity(dataTreeEntity)) {
|
||||
return getWidgetChildrenPeekData(objectName, dataTreeEntity.type, dataTree)
|
||||
?.peekData;
|
||||
return getWidgetChildrenPeekData(
|
||||
objectName,
|
||||
dataTreeEntity.type,
|
||||
dataTree,
|
||||
configTree,
|
||||
)?.peekData;
|
||||
}
|
||||
return dataTreeEntity;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class WidgetFactory {
|
|||
static stylesheetConfigMap: Map<WidgetType, Stylesheet> = new Map();
|
||||
static autocompleteDefinitions: Map<WidgetType, AutocompletionDefinitions> =
|
||||
new Map();
|
||||
static setterConfig: Map<WidgetType, Record<string, any>> = new Map();
|
||||
|
||||
static widgetConfigMap: Map<
|
||||
WidgetType,
|
||||
|
|
@ -99,6 +100,7 @@ class WidgetFactory {
|
|||
stylesheetConfig?: Stylesheet,
|
||||
autocompleteDefinitions?: AutocompletionDefinitions,
|
||||
autoLayoutConfig?: AutoLayoutConfig,
|
||||
setterConfig?: Record<string, any>,
|
||||
) {
|
||||
if (!this.widgetTypes[widgetType]) {
|
||||
this.widgetTypes[widgetType] = widgetType;
|
||||
|
|
@ -115,6 +117,7 @@ class WidgetFactory {
|
|||
this.stylesheetConfigMap.set(widgetType, stylesheetConfig);
|
||||
autocompleteDefinitions &&
|
||||
this.autocompleteDefinitions.set(widgetType, autocompleteDefinitions);
|
||||
setterConfig && this.setterConfig.set(widgetType, setterConfig);
|
||||
|
||||
if (Array.isArray(propertyPaneConfig) && propertyPaneConfig.length > 0) {
|
||||
const enhancedPropertyPaneConfig = enhancePropertyPaneConfig(
|
||||
|
|
@ -375,12 +378,22 @@ class WidgetFactory {
|
|||
type: WidgetType,
|
||||
): AutocompletionDefinitions | undefined {
|
||||
const autocompleteDefinition = this.autocompleteDefinitions.get(type);
|
||||
|
||||
if (!autocompleteDefinition) {
|
||||
log.error("Widget autocomplete properties not defined: ", type);
|
||||
}
|
||||
return autocompleteDefinition;
|
||||
}
|
||||
|
||||
static getWidgetSetterConfig(type: WidgetType): Record<string, any> {
|
||||
const map = this.setterConfig.get(type);
|
||||
|
||||
if (!map) {
|
||||
return {};
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static getLoadingProperties(type: WidgetType): Array<RegExp> | undefined {
|
||||
return this.loadingProperties.get(type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ export const registerWidget = (
|
|||
config.properties.stylesheetConfig,
|
||||
config.properties.autocompleteDefinitions,
|
||||
config.autoLayout,
|
||||
config.properties.setterConfig,
|
||||
);
|
||||
|
||||
configureWidget(config);
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ export class GracefulWorkerService {
|
|||
yield this.ready(true);
|
||||
if (!this._Worker) return;
|
||||
const messageType = MessageType.RESPONSE;
|
||||
|
||||
sendMessage.call(this._Worker, {
|
||||
body: {
|
||||
data,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeFactory";
|
||||
import type {
|
||||
ConfigTree,
|
||||
DataTree,
|
||||
DataTreeEntity,
|
||||
WidgetEntityConfig,
|
||||
} from "entities/DataTree/dataTreeFactory";
|
||||
import { ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
||||
import { uniqueId, isFunction, isObject } from "lodash";
|
||||
import { entityDefinitions } from "@appsmith/utils/autocomplete/EntityDefinitions";
|
||||
|
|
@ -18,6 +23,7 @@ export type ExtraDef = Record<string, Def | string>;
|
|||
import type { JSActionEntityConfig } from "entities/DataTree/types";
|
||||
import type { Variable } from "entities/JSCollection";
|
||||
import WidgetFactory from "utils/WidgetFactory";
|
||||
import { shouldAddSetter } from "workers/Evaluation/evaluate";
|
||||
|
||||
// Def names are encoded with information about the entity
|
||||
// This so that we have more info about them
|
||||
|
|
@ -45,12 +51,22 @@ export const dataTreeTypeDefCreator = (
|
|||
WidgetFactory.getAutocompleteDefinitions(widgetType);
|
||||
|
||||
if (autocompleteDefinitions) {
|
||||
const entityConfig = configTree[entityName] as WidgetEntityConfig;
|
||||
|
||||
if (isFunction(autocompleteDefinitions)) {
|
||||
def[entityName] = autocompleteDefinitions(entity, extraDefsToDefine);
|
||||
def[entityName] = autocompleteDefinitions(
|
||||
entity,
|
||||
extraDefsToDefine,
|
||||
entityConfig,
|
||||
);
|
||||
} else {
|
||||
def[entityName] = autocompleteDefinitions;
|
||||
}
|
||||
|
||||
addSettersToDefinitions(def[entityName] as Def, entity, entityConfig);
|
||||
|
||||
flattenDef(def, entityName);
|
||||
|
||||
entityMap.set(entityName, {
|
||||
type: ENTITY_TYPE.WIDGET,
|
||||
subType: widgetType,
|
||||
|
|
@ -218,3 +234,24 @@ export function generateJSFunctionTypeDef(
|
|||
data: generateTypeDef(jsData[fullFunctionName], extraDefs),
|
||||
};
|
||||
}
|
||||
|
||||
export function addSettersToDefinitions(
|
||||
definitions: Def,
|
||||
entity: DataTreeEntity,
|
||||
entityConfig?: WidgetEntityConfig,
|
||||
) {
|
||||
if (entityConfig && entityConfig.__setters) {
|
||||
const setters = Object.keys(entityConfig.__setters);
|
||||
|
||||
setters.forEach((setterName: string) => {
|
||||
const setter = entityConfig.__setters?.[setterName];
|
||||
const setterType = entityConfig.__setters?.[setterName].type;
|
||||
|
||||
if (shouldAddSetter(setter, entity)) {
|
||||
definitions[
|
||||
setterName
|
||||
] = `fn(value:${setterType}) -> +Promise[:t=[!0.<i>.:t]]`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
widgetSize: [
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import React from "react";
|
|||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { WidgetType } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { createBlobUrl } from "utils/AppsmithUtils";
|
||||
import type { DerivedPropertiesMap } from "utils/WidgetFactory";
|
||||
import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||
|
|
@ -236,6 +236,21 @@ class AudioRecorderWidget extends BaseWidget<
|
|||
}
|
||||
};
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const {
|
||||
blobURL,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export const CONFIG = {
|
|||
meta: Widget.getMetaPropertiesMap(),
|
||||
config: Widget.getPropertyPaneConfig(),
|
||||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import BaseWidget from "../../BaseWidget";
|
|||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants";
|
||||
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
|
||||
const AudioComponent = lazy(() => retryPromise(() => import("../component")));
|
||||
|
||||
|
|
@ -32,6 +33,25 @@ class AudioWidget extends BaseWidget<AudioWidgetProps, WidgetState> {
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setURL: {
|
||||
path: "url",
|
||||
type: "string",
|
||||
},
|
||||
setPlaying: {
|
||||
path: "autoPlay",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import type { ButtonPlacement, ButtonVariant } from "components/constants";
|
|||
import { ButtonPlacementTypes, ButtonVariantTypes } from "components/constants";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { get } from "lodash";
|
||||
import React from "react";
|
||||
import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||
|
|
@ -577,6 +577,21 @@ class ButtonGroupWidget extends BaseWidget<
|
|||
}
|
||||
};
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const { componentWidth } = this.getComponentDimensions();
|
||||
const minPopoverWidth = MinimumPopupRows * this.props.parentColumnSpace;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
defaults: {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import type { ExecutionResult } from "constants/AppsmithActionConstants/ActionCo
|
|||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { WidgetType } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import React from "react";
|
||||
import type { DerivedPropertiesMap } from "utils/WidgetFactory";
|
||||
import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||
|
|
@ -444,6 +444,29 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
|||
}
|
||||
};
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setLabel: {
|
||||
path: "text",
|
||||
type: "string",
|
||||
},
|
||||
setColor: {
|
||||
path: "buttonColor",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const disabled =
|
||||
this.props.disabledWhenInvalid &&
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
widgetSize: [
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
|||
import BaseWidget from "widgets/BaseWidget";
|
||||
import { FileDataTypes } from "widgets/constants";
|
||||
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import CameraComponent from "../component";
|
||||
import type { CameraMode } from "../constants";
|
||||
import { CameraModeTypes, MediaCaptureStatusTypes } from "../constants";
|
||||
|
|
@ -224,6 +224,21 @@ class CameraWidget extends BaseWidget<CameraWidgetProps, WidgetState> {
|
|||
return "CAMERA_WIDGET";
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const {
|
||||
bottomRow,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import contentConfig from "./propertyConfig/contentConfig";
|
|||
import styleConfig from "./propertyConfig/styleConfig";
|
||||
import type { SliderComponentProps } from "../../NumberSliderWidget/component/Slider";
|
||||
import SliderComponent from "../../NumberSliderWidget/component/Slider";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
|
||||
|
|
@ -61,6 +61,25 @@ class CategorySliderWidget extends BaseWidget<
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultOptionValue",
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: CategorySliderWidgetProps) {
|
||||
/**
|
||||
* If you change the defaultOptionValue from the propertyPane
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
defaults: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
|||
import type { TextSize, WidgetType } from "constants/WidgetConstants";
|
||||
import type { ValidationResponse } from "constants/WidgetValidation";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import { compact, xor } from "lodash";
|
||||
import { default as React } from "react";
|
||||
|
|
@ -529,6 +529,29 @@ class CheckboxGroupWidget extends BaseWidget<
|
|||
}
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setSelectedOptions: {
|
||||
path: "defaultSelectedValues",
|
||||
type: "array",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
return (
|
||||
<CheckboxGroupComponent
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { LabelPosition } from "components/constants";
|
|||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { WidgetType } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import React from "react";
|
||||
import { isAutoLayout } from "utils/autoLayout/flexWidgetUtils";
|
||||
import type { DerivedPropertiesMap } from "utils/WidgetFactory";
|
||||
|
|
@ -314,6 +314,29 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
|
|||
}
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultCheckedState",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
return (
|
||||
<CheckboxComponent
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
|||
import contentConfig from "./propertyConfig/contentConfig";
|
||||
import styleConfig from "./propertyConfig/styleConfig";
|
||||
import type { CodeScannerWidgetProps } from "../constants";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
class CodeScannerWidget extends BaseWidget<
|
||||
|
|
@ -18,6 +18,21 @@ class CodeScannerWidget extends BaseWidget<
|
|||
return contentConfig;
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisable: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneStyleConfig() {
|
||||
return styleConfig;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { ValidationTypes } from "constants/WidgetValidation";
|
|||
import { compact, map, sortBy } from "lodash";
|
||||
import WidgetsMultiSelectBox from "pages/Editor/WidgetsMultiSelectBox";
|
||||
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { Positioning } from "utils/autoLayout/constants";
|
||||
import { getSnappedGrid } from "sagas/WidgetOperationUtils";
|
||||
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
||||
|
|
@ -46,6 +46,17 @@ export class ContainerWidget extends BaseWidget<
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import {
|
|||
isAutoHeightEnabledForWidget,
|
||||
DefaultAutocompleteDefinitions,
|
||||
} from "widgets/WidgetUtils";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { NumberInputStepButtonPosition } from "widgets/BaseInputWidget/constants";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
|
||||
|
|
@ -72,12 +72,20 @@ export function defaultValueValidation(
|
|||
};
|
||||
}
|
||||
|
||||
if (_.isBoolean(value) || _.isUndefined(value) || _.isNull(value)) {
|
||||
return {
|
||||
isValid: false,
|
||||
parsed: value,
|
||||
messages: [NUMBER_ERROR_MESSAGE],
|
||||
};
|
||||
}
|
||||
|
||||
let parsed: any = Number(value);
|
||||
let isValid, messages;
|
||||
|
||||
if (_.isString(value) && value.trim() === "") {
|
||||
/*
|
||||
* When value is emtpy string
|
||||
* When value is empty string
|
||||
*/
|
||||
isValid = true;
|
||||
messages = [EMPTY_ERROR_MESSAGE];
|
||||
|
|
@ -163,6 +171,30 @@ class CurrencyInputWidget extends BaseInputWidget<
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultText",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return mergeWidgetConfig(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export const CONFIG = {
|
|||
default: Widget.getDefaultPropertiesMap(),
|
||||
meta: Widget.getMetaPropertiesMap(),
|
||||
config: Widget.getPropertyPaneConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import type { DatePickerType } from "../constants";
|
|||
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
|
||||
function defaultDateValidation(
|
||||
value: unknown,
|
||||
|
|
@ -395,6 +396,29 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
|
|||
}
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultDate",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
return (
|
||||
<DatePickerComponent
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import type { DerivedPropertiesMap } from "utils/WidgetFactory";
|
|||
|
||||
import { Alignment } from "@blueprintjs/core";
|
||||
import { LabelPosition } from "components/constants";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
|
||||
import {
|
||||
isAutoHeightEnabledForWidget,
|
||||
|
|
@ -58,6 +58,29 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultDate",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ export const CONFIG = {
|
|||
config: Widget.getPropertyPaneConfig(),
|
||||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { ValidationTypes } from "constants/WidgetValidation";
|
|||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
import { isAutoLayout } from "utils/autoLayout/flexWidgetUtils";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
|
||||
class DividerWidget extends BaseWidget<DividerWidgetProps, WidgetState> {
|
||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||
|
|
@ -24,6 +25,17 @@ class DividerWidget extends BaseWidget<DividerWidgetProps, WidgetState> {
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export const CONFIG = {
|
|||
meta: Widget.getMetaPropertiesMap(),
|
||||
config: Widget.getPropertyPaneConfig(),
|
||||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import BaseWidget from "widgets/BaseWidget";
|
|||
import DocumentViewerComponent from "../component";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
|
||||
export function documentUrlValidation(value: unknown): ValidationResponse {
|
||||
// applied validations if value exist
|
||||
|
|
@ -134,6 +135,21 @@ class DocumentViewerWidget extends BaseWidget<
|
|||
];
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setURL: {
|
||||
path: "docUrl",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||
return {
|
||||
"!doc": "Document viewer widget is used to show documents on a page",
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
defaults: {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { Colors } from "constants/Colors";
|
|||
import type { WidgetType } from "constants/WidgetConstants";
|
||||
import { FILE_SIZE_LIMIT_FOR_BLOBS } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import { klona } from "klona";
|
||||
import _, { findIndex } from "lodash";
|
||||
|
|
@ -822,6 +822,21 @@ class FilePickerWidget extends BaseWidget<
|
|||
this.state.uppy.close();
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ export const CONFIG = {
|
|||
default: Widget.getDefaultPropertiesMap(),
|
||||
meta: Widget.getMetaPropertiesMap(),
|
||||
config: Widget.getPropertyPaneConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import log from "loglevel";
|
|||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
|
||||
class FilePickerWidget extends BaseWidget<
|
||||
FilePickerWidgetProps,
|
||||
|
|
@ -471,6 +472,21 @@ class FilePickerWidget extends BaseWidget<
|
|||
this.state.uppy.close();
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
return (
|
||||
<FilePickerComponent
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
widgetSize: [
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
|||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
|
||||
class FormWidget extends ContainerWidget {
|
||||
checkInvalidChildren = (children: WidgetProps[]): boolean => {
|
||||
|
|
@ -143,6 +144,17 @@ class FormWidget extends ContainerWidget {
|
|||
});
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getDerivedPropertiesMap(): DerivedPropertiesMap {
|
||||
return { positioning: Positioning.Fixed };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
defaults: {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import BaseWidget from "widgets/BaseWidget";
|
|||
import { IconNames } from "@blueprintjs/icons";
|
||||
import type { ButtonVariant } from "components/constants";
|
||||
import { ButtonVariantTypes } from "components/constants";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import IconButtonComponent from "../component";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
|
|
@ -214,6 +214,21 @@ class IconButtonWidget extends BaseWidget<IconButtonWidgetProps, WidgetState> {
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const {
|
||||
borderRadius,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import React from "react";
|
||||
import type { WidgetState } from "widgets/BaseWidget";
|
||||
import BaseWidget from "widgets/BaseWidget";
|
||||
|
|
@ -22,6 +22,22 @@ class IframeWidget extends BaseWidget<IframeWidgetProps, WidgetState> {
|
|||
messageMetadata: generateTypeDef(widget.messageMetadata),
|
||||
});
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setURL: {
|
||||
path: "source",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ class ImageComponent extends React.Component<
|
|||
|
||||
render() {
|
||||
const { imageUrl, maxZoomLevel } = this.props;
|
||||
|
||||
const { imageError, imageRotation } = this.state;
|
||||
const zoomActive =
|
||||
maxZoomLevel !== undefined && maxZoomLevel > 1 && !this.isPanning;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import ImageComponent from "../component";
|
|||
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import type { DerivedPropertiesMap } from "utils/WidgetFactory";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
|
|
@ -28,6 +28,21 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setImage: {
|
||||
path: "image",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ export const CONFIG = {
|
|||
config: Widget.getPropertyPaneConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import {
|
|||
getLocale,
|
||||
} from "../component/utilities";
|
||||
import { LabelPosition } from "components/constants";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { checkInputTypeTextByProps } from "widgets/BaseInputWidget/utils";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
|
|
@ -127,7 +127,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
|
|||
}
|
||||
|
||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||
return {
|
||||
const definitions = {
|
||||
"!doc":
|
||||
"An input text field is used to capture a users textual input such as their names, numbers, emails etc. Inputs are used in forms and can have custom validations.",
|
||||
"!url": "https://docs.appsmith.com/widget-reference/input",
|
||||
|
|
@ -148,6 +148,8 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
|
|||
"!doc": "Selected country code for Currency type input",
|
||||
},
|
||||
};
|
||||
|
||||
return definitions;
|
||||
}
|
||||
|
||||
static getPropertyPaneConfig() {
|
||||
|
|
@ -763,6 +765,29 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultText",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
onValueChange = (value: string) => {
|
||||
this.props.updateWidgetMetaProperty("text", value, {
|
||||
triggerPropertyName: "onTextChanged",
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ import {
|
|||
InputTypes,
|
||||
NumberInputStepButtonPosition,
|
||||
} from "widgets/BaseInputWidget/constants";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { getParsedText, isInputTypeEmailOrPassword } from "./Utilities";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import {
|
||||
isAutoHeightEnabledForWidget,
|
||||
DefaultAutocompleteDefinitions,
|
||||
|
|
@ -59,14 +59,20 @@ export function defaultValueValidation(
|
|||
}
|
||||
|
||||
const { inputType } = props;
|
||||
|
||||
if (_.isBoolean(value) || _.isNil(value) || _.isUndefined(value)) {
|
||||
return {
|
||||
isValid: false,
|
||||
parsed: value,
|
||||
messages: [STRING_ERROR_MESSAGE],
|
||||
};
|
||||
}
|
||||
|
||||
let parsed;
|
||||
switch (inputType) {
|
||||
case "NUMBER":
|
||||
if (_.isNil(value)) {
|
||||
parsed = null;
|
||||
} else {
|
||||
parsed = Number(value);
|
||||
}
|
||||
|
||||
let isValid, messages;
|
||||
|
||||
if (_.isString(value) && value.trim() === "") {
|
||||
|
|
@ -262,7 +268,7 @@ function InputTypeUpdateHook(
|
|||
|
||||
class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||
return {
|
||||
const definitions: AutocompletionDefinitions = {
|
||||
"!doc":
|
||||
"An input text field is used to capture a users textual input such as their names, numbers, emails etc. Inputs are used in forms and can have custom validations.",
|
||||
"!url": "https://docs.appsmith.com/widget-reference/input",
|
||||
|
|
@ -275,6 +281,8 @@ class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
|||
isVisible: DefaultAutocompleteDefinitions.isVisible,
|
||||
isDisabled: "bool",
|
||||
};
|
||||
|
||||
return definitions;
|
||||
}
|
||||
static getPropertyPaneContentConfig() {
|
||||
return mergeWidgetConfig(
|
||||
|
|
@ -590,6 +598,29 @@ class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
|||
}
|
||||
};
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultText",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
resetWidgetText = () => {
|
||||
this.props.updateWidgetMetaProperty("inputText", "");
|
||||
this.props.updateWidgetMetaProperty(
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
widgetSize: [
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { convertSchemaItemToFormData } from "../helper";
|
|||
import type {
|
||||
ButtonStyles,
|
||||
ChildStylesheet,
|
||||
SetterConfig,
|
||||
Stylesheet,
|
||||
} from "entities/AppTheming";
|
||||
import type { BatchPropertyUpdatePayload } from "actions/controlActions";
|
||||
|
|
@ -223,7 +224,8 @@ class JSONFormWidget extends BaseWidget<
|
|||
}
|
||||
|
||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||
return (widget: JSONFormWidgetProps) => ({
|
||||
return (widget: JSONFormWidgetProps) => {
|
||||
const definitions: AutocompletionDefinitions = {
|
||||
"!doc":
|
||||
"JSON Form widget can be used to auto-generate forms by providing a JSON source data.",
|
||||
// TODO: Update the url
|
||||
|
|
@ -232,7 +234,25 @@ class JSONFormWidget extends BaseWidget<
|
|||
sourceData: generateTypeDef(widget.sourceData),
|
||||
fieldState: generateTypeDef(widget.fieldState),
|
||||
isValid: "bool",
|
||||
});
|
||||
};
|
||||
|
||||
return definitions;
|
||||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setSourceData: {
|
||||
path: "sourceData",
|
||||
type: "object",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static defaultProps = {};
|
||||
|
|
|
|||
|
|
@ -33,6 +33,19 @@ export const sourceDataValidationFn = (
|
|||
};
|
||||
}
|
||||
|
||||
if (_.isNumber(value) || _.isBoolean(value)) {
|
||||
return {
|
||||
isValid: false,
|
||||
parsed: {},
|
||||
messages: [
|
||||
{
|
||||
name: "ValidationError",
|
||||
message: `Source data cannot be ${value}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (_.isNil(value)) {
|
||||
return {
|
||||
isValid: true,
|
||||
|
|
|
|||
|
|
@ -418,6 +418,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
|||
import type { WidgetType } from "constants/WidgetConstants";
|
||||
import { GridDefaults, RenderModes } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import type { PrivateWidgets } from "entities/DataTree/types";
|
||||
import equal from "fast-deep-equal/es6";
|
||||
import { klona } from "klona/lite";
|
||||
|
|
@ -79,6 +79,18 @@ class ListWidget extends BaseWidget<ListWidgetProps<WidgetProps>, WidgetState> {
|
|||
pageSize: generateTypeDef(widget.pageSize),
|
||||
});
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return PropertyPaneContentConfig;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -477,6 +477,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
widgetSize: [
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import { RenderModes, WIDGET_PADDING } from "constants/WidgetConstants";
|
|||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { ModifyMetaWidgetPayload } from "reducers/entityReducers/metaWidgetsReducer";
|
||||
import type { WidgetState } from "../../BaseWidget";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import type {
|
||||
TabContainerWidgetProps,
|
||||
TabsWidgetProps,
|
||||
|
|
@ -159,13 +159,15 @@ class ListWidget extends BaseWidget<
|
|||
}
|
||||
|
||||
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
||||
return (widget: ListWidgetProps, extraDefsToDefine?: ExtraDef) => ({
|
||||
return (widget: ListWidgetProps, extraDefsToDefine?: ExtraDef) => {
|
||||
const obj = {
|
||||
"!doc":
|
||||
"Containers are used to group widgets together to form logical higher order widgets. Containers let you organize your page better and move all the widgets inside them together.",
|
||||
"!url": "https://docs.appsmith.com/widget-reference/list",
|
||||
backgroundColor: {
|
||||
"!type": "string",
|
||||
"!url": "https://docs.appsmith.com/widget-reference/how-to-use-widgets",
|
||||
"!url":
|
||||
"https://docs.appsmith.com/widget-reference/how-to-use-widgets",
|
||||
},
|
||||
isVisible: DefaultAutocompleteDefinitions.isVisible,
|
||||
itemSpacing: "number",
|
||||
|
|
@ -186,7 +188,21 @@ class ListWidget extends BaseWidget<
|
|||
widget.currentItemsView,
|
||||
extraDefsToDefine,
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getDerivedPropertiesMap() {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Skeleton from "components/utils/Skeleton";
|
|||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { WidgetType } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import { retryPromise } from "utils/AppsmithUtils";
|
||||
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
|
||||
|
|
@ -78,6 +78,18 @@ class MapChartWidget extends BaseWidget<MapChartWidgetProps, WidgetState> {
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import MapComponent from "../component";
|
|||
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import styled from "styled-components";
|
||||
import type { DerivedPropertiesMap } from "utils/WidgetFactory";
|
||||
|
|
@ -67,6 +67,17 @@ class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static getPropertyPaneContentConfig() {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
defaults: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { ExecuteTriggerPayload } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { isArray, orderBy } from "lodash";
|
||||
import { default as React } from "react";
|
||||
import type { WidgetState } from "widgets/BaseWidget";
|
||||
|
|
@ -114,6 +114,21 @@ class MenuButtonWidget extends BaseWidget<MenuButtonWidgetProps, WidgetState> {
|
|||
return [];
|
||||
};
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const { componentWidth } = this.getComponentDimensions();
|
||||
const menuDropDownWidth = MinimumPopupRows * this.props.parentColumnSpace;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Layers } from "constants/Layers";
|
|||
import type { TextSize, WidgetType } from "constants/WidgetConstants";
|
||||
import type { ValidationResponse } from "constants/WidgetValidation";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import { isArray, xor } from "lodash";
|
||||
import type { DefaultValueType } from "rc-tree-select/lib/interface";
|
||||
|
|
@ -561,6 +561,25 @@ class MultiSelectTreeWidget extends BaseWidget<
|
|||
}
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const options = isArray(this.props.options) ? this.props.options : [];
|
||||
const dropDownWidth = MinimumPopupRows * this.props.parentColumnSpace;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ export const CONFIG = {
|
|||
config: Widget.getPropertyPaneConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import BaseWidget from "widgets/BaseWidget";
|
|||
import { Alignment } from "@blueprintjs/core";
|
||||
import { LabelPosition } from "components/constants";
|
||||
import { Layers } from "constants/Layers";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import type { DraftValueType } from "rc-select/lib/Select";
|
||||
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
|
||||
|
|
@ -447,6 +447,29 @@ class MultiSelectWidget extends BaseWidget<
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setSelectedOptions: {
|
||||
path: "defaultOptionValue",
|
||||
type: "array",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const options = isArray(this.props.options) ? this.props.options : [];
|
||||
const values: string[] = isArray(this.props.selectedOptionValues)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Layers } from "constants/Layers";
|
|||
import type { WidgetType } from "constants/WidgetConstants";
|
||||
import type { ValidationResponse } from "constants/WidgetValidation";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import equal from "fast-deep-equal/es6";
|
||||
import type { LoDashStatic } from "lodash";
|
||||
|
|
@ -714,6 +714,29 @@ class MultiSelectWidget extends BaseWidget<
|
|||
}
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setRequired: {
|
||||
path: "isRequired",
|
||||
type: "boolean",
|
||||
},
|
||||
setSelectedOptions: {
|
||||
path: "defaultOptionValue",
|
||||
type: "array",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const options = isArray(this.props.options) ? this.props.options : [];
|
||||
const minDropDownWidth = MinimumPopupRows * this.props.parentColumnSpace;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import type { SliderComponentProps } from "../component/Slider";
|
|||
import SliderComponent from "../component/Slider";
|
||||
import contentConfig from "./propertyConfig/contentConfig";
|
||||
import styleConfig from "./propertyConfig/styleConfig";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
|
||||
|
|
@ -59,6 +59,25 @@ class NumberSliderWidget extends BaseWidget<
|
|||
};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setValue: {
|
||||
path: "defaultValue",
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: NumberSliderWidgetProps) {
|
||||
/**
|
||||
* If you change the defaultValue from the propertyPane
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import { AsYouType, parseIncompletePhoneNumber } from "libphonenumber-js";
|
|||
import * as Sentry from "@sentry/react";
|
||||
import log from "loglevel";
|
||||
import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import {
|
||||
isAutoHeightEnabledForWidget,
|
||||
DefaultAutocompleteDefinitions,
|
||||
|
|
@ -365,6 +365,21 @@ class PhoneInputWidget extends BaseInputWidget<
|
|||
this.props.updateWidgetMetaProperty("value", undefined);
|
||||
};
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const value = this.props.text ?? "";
|
||||
const isInvalid =
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
disabledPropsDefaults: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import BaseWidget from "widgets/BaseWidget";
|
|||
|
||||
import { Colors } from "constants/Colors";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import ProgressComponent from "../component";
|
||||
import { ProgressType, ProgressVariant } from "../constants";
|
||||
import type { AutocompletionDefinitions } from "widgets/constants";
|
||||
|
|
@ -188,6 +188,21 @@ class ProgressWidget extends BaseWidget<ProgressWidgetProps, WidgetState> {
|
|||
return {};
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setProgress: {
|
||||
path: "progress",
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const {
|
||||
borderRadius,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export const CONFIG = {
|
|||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
},
|
||||
autoLayout: {
|
||||
defaults: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
|||
import type { TextSize, WidgetType } from "constants/WidgetConstants";
|
||||
import type { ValidationResponse } from "constants/WidgetValidation";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
|
||||
import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
|
||||
|
|
@ -572,6 +572,25 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
|
|||
}
|
||||
}
|
||||
|
||||
static getSetterConfig(): SetterConfig {
|
||||
return {
|
||||
__setters: {
|
||||
setVisibility: {
|
||||
path: "isVisible",
|
||||
type: "boolean",
|
||||
},
|
||||
setDisabled: {
|
||||
path: "isDisabled",
|
||||
type: "boolean",
|
||||
},
|
||||
setData: {
|
||||
path: "options",
|
||||
type: "array",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
const {
|
||||
alignment,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ export const CONFIG = {
|
|||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||
stylesheetConfig: Widget.getStylesheetConfig(),
|
||||
setterConfig: Widget.getSetterConfig(),
|
||||
autocompleteDefinitions: Widget.getAutocompleteDefinitions(),
|
||||
},
|
||||
autoLayout: {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user