From c287b4d78190d5ddef5bf37c0dc10d9f4eab6a0c Mon Sep 17 00:00:00 2001 From: ankurrsinghal Date: Fri, 25 Nov 2022 00:10:06 +0530 Subject: [PATCH] fix: auto height regression fixes (#18410) * removed block and added flex consistent in the alignment case of left and right * fixed radio group which broke because of display block * default enabled auto height for every widget * added reivew changes * reverted the switch group style changes and added the check for Text widget background in the AutoHeightContainer * changed the scroll helper text for containers * reverted the default enable for all the widgets * test: fixed DH flaky test (#18415) fixed DH flaky test * fix: auto height container computations (#18408) * Fix auto height container computations * fix: Invisible Widgets Overlap while switching back and forth between edit and preview modes in rare cases (#18398) sort Space based on original position if dynamic positions are equal while generating tree * fix: group widgets label alignment. (#18360) * fix: group widgets label alignment. * fix: switch and radio fix transform styles for auto height. * feat: disable auto height limits for modal (#18386) * added multi select back * (WIP): Complete the dynamc height update logic * (WIP): Dynamic height logic * (WIP): Container computation logic, Next steps: Prevent reflow when resize is disabled. Fix logic of widgets randomly changing positions (Debug) * Fix logic in container computations * Integrate for PoC * fixed the no initial load dynamic height updates * Stop vertical resize and reflow when dynamic height is enabled for a widget * added another container in text widget * enabled dynamic height for container widgets * removed dynamic height feature from list widget * Fixed Button and Input components height increase * added an experiment to overflow the content if maxHEight is less * removed the ref of Textwidget by mistake, added it back * fixed text widget height overflow problem with a little hack * added long labels with text * fixed the table scroll issue * overflow fixed for json form widget * added extra 8px height for Switch, Rating and Checkbox Height * (WIP): Resolve issues * (WIP): Fix widget padding issue * added overflow container for Radio and Switch group widgets * (WIP): Have modals work with dynamic height * added the overlay and the handles * added dragging behavior to the dots * fixed the overlapping with the selection tool * (WIP): Fix issues reported * now we can update the property pane values back from overlay handles * now we can update the property pane values back from overlay handles * (WIP): Fix table widget * Fix package.json * Remove unit tests temporarily * Fix unit test * (WIP): Fix modal resize. Fix cursors. Fix border issue on non-resizable widgets * fetch component heights using the requestAnimationFrame callback * behavioural changes * (WIP): Fix issues on the platform * Update main container size appropriately * more behavioural changes * overlay now only be visible when hovering over the dots * grid showing and widget reselecting * added onfocus and onblur events to property pane listeners * added onfocus and onblur events to property pane listeners * added a range slider for min and max * added demarcations for slider values * (WIP): Fix platform workflows for dynamic height * Fix issues with widgets * Fix removed import * - Add missing cypress files * set the limits * limit increase on change * Fix z-index of min max limit indicators. Fix unused-vars warnings * Fix Table Widget and Text Widget issues * Fix: all the bugs in the bug master list for DH (#16268) * changed the zindex for the signifiers * showing signifiers only when the widget is selected * made changes suggested by Momcilo * activate the dots when the fields are active * created a new centered dot handle * removed overlays on focus and made the border more like deisgn * handles on top of other widgets * hide the overlay when multiple widgets are selected * added a white border * added a white border * bug #15509 resolved * changed the minDynamicHeightLimit to 2 instead of 4 to fix the Bug #15527 * removed the height auto fix from BaseInputComponent to fix the Bug #15388 * removed the condition to not ccalculate dynamic height when the row difference is less than 2 to fix the bug 15353 * made fixes for the bug #16307 * made fixes for the bug #16308 * made fixes for bug 16310 * made fixes for the bug #16402 * removed some log statements * made fixes for the bug #16407 * fixed label problem found in the issue #16543 * made fixes for the issue #16547 * made fixes for the bug #16492 * redeploy * (WIP): Fix to make this branch functional * imported LabelWithTooltip back from design system * signifier is now centered * filled the signifier with primary color * overlay hidden while dragging * made the signifier dashed border also draggable * Fix issue #16590 (#16798) * set the limits to 4 rows * replaced the static 40 value * added signifiers for modal widget * added signifiers for modal widget * tried solving the scroll issue for widgets when there are limits * solved the height problem using ResizeObserver * (WIP): Fix maxDynamicHeight issue with container widgets: * made the changes as per the review * fixed the issue for input widget when label gets out of border * hide text widget overflow options if auto height is enabled * (WIP): In view mode, invisible widgets now donot take space (#16920) * (WIP): In view mode, invisible widgets now donot take space * (WIP): Enable the feature where invisible widgets in view mode don't take space to all widgets irrespective of the dynamic height feature * Remove Replay conditional * removed the scroll container for container type widgets * removed the scroll container for container type widgets * updated the hook to set overflow none for text widget * fixed the should dynamic height logic to respect the min height limit * Modal widget adheres to dynamic height (#16995) * Modal widget adheres to dynamic height * WIP: POC: fix dynamic height issues (#16996) Fix height less than 4 issue. Fix JSONForm adherence to min and max height * POC: Dynamic height undo redo issue (#17085) * Revert debouce timeout * (WIP): Fix issue with undo-redo in dynamic height * fix: Dynamic height issue fixes (#17153) * Dynamic height issue fixes == - Fix issue where nested widgets did not ensure parent dynamic height updates - Fix issue where Modal widget updates came in subsequent renders - Fix issue where JSONForm collapses - Fix performance issue for independent updates * Use functions to get min and max dynamic height * Fix issue where variable might have been undefined * added the dynamic container into the deploy mode as well * added overflow-x hidden when overflow-y is active in the dynamic height container * fix: Dynamic height Issue fixes (#17204) Fix preview mode invisible widgets. Fix Tabs widget dynamic height. * removed a console.log statement * removed the slider control file * imported the LabelWithTooltip from the repo rather than ds * word-break CSS rules added for Switch and Checkbox widget when Dynamic Height is enabled * abstracted the check for dynamic height with limits enabled as isDynamicHeightWithLimitsEnabledForWidget * abstracted the static value of 10 in dynamic height overlay to GridDefaults * abstracted min and max dynamic height limits to getters * fix: replaced all the refs for simpler widgets (#17353) * replaced all the refs for simpler widgets * removed the updateDynamicHeight from componentDidUpdate in BaseWidget * added back lifecycle methods back to BaseWidget * removed the contentRef from SwitchGroup and Table * updating the height from the auto height with limits as well * some hacks to make the limits work * working solution * used setTimeout to send an update to updateDynamicHeight from overlay update * removed a log * added requestanimationframe in settimeout Co-authored-by: Ankur Singhal Co-authored-by: Ankur Singhal * Fix issues caused during merge * Remove unneeded derived property * removed more unnecessary code which should have been removed after removing the ref dependency * fixed the maxDynamicHeight issue * Fix issue where property configs were not being sent * fix: Auto Height Feature - add selectors for tests (#17687) Add selectors for auto height cypress tests * fix: removed height auto default theme (#17415) removed height auto css rule from the default theme Co-authored-by: Ankur Singhal * fix: Auto Height Feature - Resolve issues and restructure code (#17686) * Fix issues in dynamic height. Restructure code and reduce abstraction leaks * Fix typescript issues * Update based on review comments. Comment migrations, as a cyclic import is causing the jest tests to fail. * Remove unused imports * Decrease code nesting * added the base styles for the overlay like position and z-index in its styled component css * used the isDynamicHeightEnabled prop to set the height of SwitchGroup and RadioGroup widgets from 32px to 100% in case of inline mode * fix: Auto Height - Resolve issues (#17737) * Fix Tabs Widget showTabs toggle based auto height. Revert removal of BaseWidget code. Remove box-intersect and use a bruteforce algorithm. Add base logic for having containers collapse due to hidden child widgets * Hide scroll contents and overflow property pane controls when dynamic height is enabled * Removed the class property expectedHeight from BaseWidget as it is not useful in the overlay logic after some changes * fixed the left alignment issue of label in the rich text editor by adding some styles applied only when the dynamic height is enabled * fixed the input field stretching issue in case of Dynamic height by adding some CSS styles when isDynamicHeight is true * Fix failing modal widget cypress tests * Fix issue with scrollContents and Tabs Widget defaulTab * added a little bit padding of 4px to the right of scroll container of dynamic height with limit * Add test locators for resize handles * removed the dynamic height logic from the table widget * fix: Auto-Height invisible widgets (#17849) * Fix issue where invisible widgets were still taking space * Make sure to collapse only if dynamic height is enabled * Fix issues with reflow (not the invisible widgets) * Fix container min height issues * Fix reflow with original bottom and top values. Testing needed * Fix invisible widgets * fix: enabled dynamic height for stat box widget (#17971) enabled dynamic height for stat box widget Co-authored-by: Ankur Singhal * fix: added a min height to rich text editor so that it does not collapse (#17970) added a min height to rich text editor so that it does not collapse Co-authored-by: Ankur Singhal * Fix issue with resizing auto height widget * Add helper text to educate users regarding the scroll disconnect in WYSIWYG * fix: Auto Height Fixes (#18111) AUTO HEIGHT FIXES - Fix JSONForm height discrepancy - Fix issue where widgets moved below the other - Fix droptarget height after parent container resize * fix: sliced up the DynamicHeightOverlay component a little bit (#18100) * sliced up the DynamicHeightOverlay component a little bit * more refactoring * more refactoring * used release event emitter and refactored more Co-authored-by: Ankur Singhal * fix: rich text editor center alignment issue (#18142) * removed the center alignment from rich text editor * dummy commit Co-authored-by: Ankur Singhal * fix: old DSL container collapse (#18160) * Fix issue where old containers from old DSLs used to collapse when auto height was enabled * Fix issue where old containers don't allow new widgets to be added when auto height is enabled, this is because the shouldScrollContents is undefined * fix: input widgets issue (#18172) fixed the auto height not working issue Co-authored-by: Ankur Singhal * fix: preview deploy mode (#18174) fixed the preview and deploy mode Co-authored-by: Ankur Singhal * fix: auto height limits label intersection with handle dot (#18186) fixed the position of the limits label to the right so that it will not intersect with the handle dot Co-authored-by: Ankur Singhal * fix: auto height limits rich text editor min height (#18187) decrease the min height of the RTE so that it does not have the boundary issue with the max limit when auto height with limits is enabled Co-authored-by: Ankur Singhal * fix: grammatical error in the help text (#18188) changed react to reacts in the helpText of the dynamic height property in the proeprty pane Co-authored-by: Ankur Singhal * fix: auto height tabs double scroll (#18210) solved the issue by disabling the scroll for the child canvas widget in the tabs widget Co-authored-by: Ankur Singhal * fix: auto height limits resizing (#18213) * fixed the auto height limits resizing issue * made the auto height overlay independent of isResizing and used its own property to show the grid * some more refactoring Co-authored-by: Ankur Singhal * dummy commit * fix: old apps container issue (#18255) filtered out the widgets which are detached from layout Co-authored-by: Ankur Singhal * fix: fixing auto height in childless containers. (#18263) fixing auto height in childless containers. * task: Dynamic height reflow fixes in Branch (#18244) dynamic height reflow fixes * fix: compact label issue and min and max limits numeric input (#18282) fixed compact label issue and turned min and max limits to numeric input Co-authored-by: Ankur Singhal * fix: LabelWithTooltip help icon fix * fix: NaN and min limit for min and max (#18284) * fixed compact label issue and turned min and max limits to numeric input * fixed NaN and set min to be 4 Co-authored-by: Ankur Singhal * fix: validation issues for min max (#18286) * fixed compact label issue and turned min and max limits to numeric input * fixed NaN and set min to be 4 * validations start working min max Co-authored-by: Ankur Singhal * added a full stop to container scroll helper text * validations start working min max * dummy commit * feat: stop resizing auto height widgets vertically because of Drag n Drop Reflow (#18267) * reflow fixes * stop resizing auto height widgets vertically because of Drag n Drop Reflow * feat: Analytics for Dynamic height (#18279) * Fix canvas min height issue and invisible widgets issue and remove logs and fix issue where widgets overlapped when coming back from preview mode to edit mode * Fix issue with containers not respecting auto height and decreasing height * Fix issue with modal widget not hugging contents, and container widgets never become visible after going invisible * Fix issue where existing containers don't have correct min height for child canvas * fix: canvasLevelsReducers test (#18301) fixed the canvasLevelsReducers test Co-authored-by: Ankur Singhal * fix: removed auto height min max config from widget features (#18316) removed auto height min max config from widget features Co-authored-by: Ankur Singhal * fix: Fixing Modal Height updates (#18317) Fixing Modal Height updates * fix: text widget background auto height (#18319) added background color of Text widget back to the auto height container Co-authored-by: Ankur Singhal * test: cypress tests for auto height (#17676) * Added tests for dynamic height * updated tests for another usecase * moved locators into commonfile * updated common method * added tests for some more widgets * Added tests for jsonForm / Form widget * Updated the test * updated test for multiple text widgets * updated test with few more usecases * updated the dsl * updated tests for text change * updated tests based on new changes * updated cypress test fixes * fix: auto height container merge poc wrt release (#18334) updated the poc wrt PR already merged in the release regarding the auto height container Co-authored-by: Ankur Singhal * fix: renamed auto height overlay components and added some tests (#18333) * renamed auto height overlay components and added some tests * replaced the 10 value with GridDefaults * avoiding event to reach drop target Co-authored-by: Ankur Singhal * updated tests * Merge all code into one branch * Fix failing AutoHeightcontainer test * fix: Fix reflow computations which were causing widget overlap (#18300) * Fix reflow computations which were causing widget overlap * Fix issues with parent container height and overlapping widgets * Remove console logs * Revert comment * Fix issues related to reflow of containers * feat: Making getEffectedBoxes a Recursive function in autoHeight Reflow (#18336) Making getEffectedBoxes a Recursive function in autoHeight Reflow * Return null for invisible widgets from withWidgetProps * Remove duplicate import Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com> * Remove missed console log * fix: Label position gets deselected on selecting already selected option (#18298) * fix: Label position gets deselected on selecting the already selected value * Added migration for Currency & Phone input widgets * simplify migration function using a utility * combine conditions * Increments LATEST_PAGE_VERSION * Update DynamicHeight_Visibility_spec.js updated a check wrt auto height * Handling Modals for canvas size calculations * fix: migrate label position test failing issue (#18365) fixed migrate label postition test failing issue Co-authored-by: Ankur Singhal * removed the two unwanted imports from DSLMigrations to fix client build * fix: Auto height zero and limits issue (#18366) fixed the auto height zero and limits issue Co-authored-by: Ankur Singhal * fix: Auto height regression issues (#18367) * Fix auto height regression issues #18367 * feat: auto height migrations (#18368) Add auto height migrations * Increase file caching size * Use manual array for list of auto height enabled widgets * Fix cypress test dsl versions * Revert changes to shouldUpdateHeightDynamically * Update test results based on code changes * Marginally increase the workbox file size cache * review comment incorporated for test spec * Update container auto height property on drop * Disable auto height with limits for modal Co-authored-by: Ankur Singhal Co-authored-by: rahulramesha Co-authored-by: Abhinav Jha Co-authored-by: Ankur Singhal Co-authored-by: Ankur Singhal Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com> Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com> Co-authored-by: Albin Co-authored-by: Aswath K Co-authored-by: NandanAnantharamu <67676905+NandanAnantharamu@users.noreply.github.com> Co-authored-by: Apple * chore: Moved height property to General section (#18402) * fix: Height property is moved to General section * Logs an Error if section is not General * fix: Cypress * enabled auto height for all the widgets except json form * removes accidentally committed files Co-authored-by: Ankur Singhal * disabled default auto height for input widgets and select widgets and datepicker widget * feat: Disable auto height for widgets in List Widget (#18381) * Remove auto height for container Inside List widget * remove unneccessary changes * disable feature at generalConfig instead of firstConfig * add todo comment * skipped the get min limit tests * fixed AutoHeightLimitHandleDot tests * Updated cypress tests for regression changes * update visual tests for widget layout Co-authored-by: Ankur Singhal Co-authored-by: NandanAnantharamu <67676905+NandanAnantharamu@users.noreply.github.com> Co-authored-by: Abhinav Jha Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com> Co-authored-by: Arsalan Yaldram Co-authored-by: rahulramesha Co-authored-by: Abhinav Jha Co-authored-by: Ankur Singhal Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com> Co-authored-by: Albin Co-authored-by: Aswath K Co-authored-by: Apple Co-authored-by: Parthvi Goswami --- .../dynamicHeightContainerCheckboxdsl.json | 170 +++++++++++ .../fixtures/dynamicHeightContainerdsl.json | 183 ++++-------- .../fixtures/dynamicHeightStatboxdsl.json | 281 ++++++++++++++++++ .../DynamicHeight_Auto_Height_Limit_spec.js | 4 +- .../DynamicHeight_Auto_Height_spec.js | 6 +- ...ynamicHeight_Form_With_SwitchGroup_spec.js | 2 +- .../DynamicHeight_Multiple_Container_spec.js | 8 +- .../DynamicHeight_Visibility_spec.js | 92 +++--- .../VisualTests/WidgetsLayout_spec.js | 9 +- .../Widgets/Others/Statbox_spec.js | 4 +- .../inlineDisabled.snap.png | Bin 2086 -> 4689 bytes .../inlineEnabled.snap.png | Bin 4282 -> 4308 bytes app/client/cypress/support/widgetCommands.js | 4 +- .../autoHeight/AutoHeightContainer.tsx | 5 +- .../components/autoHeightOverlay/constants.ts | 4 + .../components/autoHeightOverlay/index.tsx | 13 +- .../ui/AutoHeightLimitHandleDot.test.tsx | 4 +- .../ui/AutoHeightLimitHandleDot.tsx | 6 +- app/client/src/constants/DefaultTheme.tsx | 46 +-- app/client/src/constants/Layers.tsx | 2 + app/client/src/constants/WidgetConstants.tsx | 1 + app/client/src/pages/AppViewer/index.tsx | 7 +- .../Editor/PropertyPane/PropertyPaneView.tsx | 4 +- app/client/src/sagas/ReplaySaga.ts | 3 +- .../src/sagas/autoHeightSagas/containers.ts | 251 +++++++++------- .../src/sagas/autoHeightSagas/helpers.ts | 18 +- .../src/sagas/autoHeightSagas/widgets.ts | 104 ++++--- .../src/selectors/propertyPaneSelectors.tsx | 3 + app/client/src/utils/WidgetFactory.tsx | 1 + app/client/src/utils/WidgetFactoryHelpers.ts | 18 +- app/client/src/utils/WidgetFeatures.ts | 101 ++++++- .../src/utils/autoHeight/generateTree.ts | 10 +- .../CheckboxGroupWidget/component/index.tsx | 7 +- .../src/widgets/CheckboxGroupWidget/index.ts | 5 +- .../CheckboxGroupWidget/widget/index.tsx | 30 +- .../src/widgets/CheckboxWidget/index.ts | 5 +- .../src/widgets/ContainerWidget/index.ts | 8 +- .../src/widgets/CurrencyInputWidget/index.ts | 7 +- .../src/widgets/DatePickerWidget2/index.ts | 7 +- app/client/src/widgets/FormWidget/index.ts | 5 +- app/client/src/widgets/InputWidgetV2/index.ts | 7 +- .../widgets/JSONFormWidget/component/Form.tsx | 4 +- .../component/useFixedFooter.ts | 7 +- .../src/widgets/JSONFormWidget/index.ts | 7 +- .../widgets/JSONFormWidget/widget/index.tsx | 44 --- app/client/src/widgets/ListWidget/index.ts | 4 + app/client/src/widgets/ModalWidget/index.ts | 6 +- .../widgets/MultiSelectTreeWidget/index.ts | 7 +- .../src/widgets/MultiSelectWidgetV2/index.ts | 7 +- .../src/widgets/PhoneInputWidget/index.ts | 7 +- .../RadioGroupWidget/component/index.tsx | 17 +- .../src/widgets/RadioGroupWidget/index.ts | 5 +- .../widgets/RadioGroupWidget/widget/index.tsx | 20 +- app/client/src/widgets/RateWidget/index.ts | 5 +- .../src/widgets/RichTextEditorWidget/index.ts | 7 +- app/client/src/widgets/SelectWidget/index.ts | 7 +- .../widgets/SingleSelectTreeWidget/index.ts | 7 +- app/client/src/widgets/StatboxWidget/index.ts | 6 +- .../SwitchGroupWidget/component/index.tsx | 10 +- .../src/widgets/SwitchGroupWidget/index.ts | 5 +- .../SwitchGroupWidget/widget/index.tsx | 16 +- .../widgets/SwitchWidget/component/index.tsx | 4 - app/client/src/widgets/SwitchWidget/index.ts | 5 +- app/client/src/widgets/TabsWidget/index.ts | 10 +- app/client/src/widgets/TextWidget/index.ts | 5 +- app/client/src/widgets/WidgetUtils.test.ts | 4 +- app/client/src/widgets/WidgetUtils.ts | 6 +- app/client/src/widgets/withWidgetProps.tsx | 5 +- 68 files changed, 1160 insertions(+), 522 deletions(-) create mode 100644 app/client/cypress/fixtures/dynamicHeightContainerCheckboxdsl.json create mode 100644 app/client/cypress/fixtures/dynamicHeightStatboxdsl.json diff --git a/app/client/cypress/fixtures/dynamicHeightContainerCheckboxdsl.json b/app/client/cypress/fixtures/dynamicHeightContainerCheckboxdsl.json new file mode 100644 index 0000000000..a945fec106 --- /dev/null +++ b/app/client/cypress/fixtures/dynamicHeightContainerCheckboxdsl.json @@ -0,0 +1,170 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 4896, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1290, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 69, + "minHeight": 1292, + "dynamicTriggerPathList": [], + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "widgetName": "Container1", + "borderColor": "#E0DEDE", + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg", + "searchTags": [ + "div", + "parent", + "group" + ], + "topRow": 6, + "bottomRow": 16, + "parentRowSpace": 10, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "shouldScrollContents": true, + "animateLoading": true, + "parentColumnSpace": 11.9375, + "leftColumn": 16, + "dynamicBindingPathList": [ + { + "key": "borderRadius" + }, + { + "key": "boxShadow" + } + ], + "children": [ + { + "boxShadow": "none", + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0, + "bottomRow": 100, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "minHeight": 100, + "parentColumnSpace": 1, + "leftColumn": 0, + "dynamicBindingPathList": [ + { + "key": "borderRadius" + }, + { + "key": "accentColor" + } + ], + "children": [ + { + "isVisible": true, + "animateLoading": true, + "labelTextSize": "0.875rem", + "options": [ + { + "label": "Blue", + "value": "BLUE" + }, + { + "label": "Green", + "value": "GREEN" + }, + { + "label": "Red", + "value": "RED" + } + ], + "defaultSelectedValues": [ + "BLUE" + ], + "isDisabled": false, + "isInline": true, + "isRequired": false, + "labelText": "Label", + "labelPosition": "Top", + "labelAlignment": "left", + "labelWidth": 5, + "widgetName": "CheckboxGroup1", + "version": 2, + "minDynamicHeight": 4, + "maxDynamicHeight": 9000, + "dynamicHeight": "AUTO_HEIGHT", + "type": "CHECKBOX_GROUP_WIDGET", + "hideCard": false, + "isDeprecated": false, + "displayName": "Checkbox Group", + "key": "px8e5kndcb", + "iconSVG": "/static/media/icon.ecb3847950c4515966ef642a32758afb.svg", + "widgetId": "li1gq4tzny", + "renderMode": "CANVAS", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "isLoading": false, + "parentColumnSpace": 3.42578125, + "parentRowSpace": 10, + "leftColumn": 18, + "rightColumn": 41, + "topRow": 0, + "bottomRow": 6, + "parentId": "tbezx4vcxu", + "dynamicBindingPathList": [ + { + "key": "accentColor" + }, + { + "key": "borderRadius" + } + ] + } + ], + "key": "49f4d77rwd", + "isDeprecated": false, + "rightColumn": 286.5, + "detachFromLayout": true, + "widgetId": "tbezx4vcxu", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "containerStyle": "none", + "isVisible": true, + "version": 1, + "parentId": "57nv0ufxq1", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + } + ], + "borderWidth": "1", + "key": "g4phrz9m3l", + "backgroundColor": "#FFFFFF", + "isDeprecated": false, + "rightColumn": 40, + "dynamicHeight": "AUTO_HEIGHT", + "widgetId": "57nv0ufxq1", + "containerStyle": "card", + "isVisible": true, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "maxDynamicHeight": 9000, + "minDynamicHeight": 10 + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/dynamicHeightContainerdsl.json b/app/client/cypress/fixtures/dynamicHeightContainerdsl.json index 6ce3c925a9..a59bd714fb 100644 --- a/app/client/cypress/fixtures/dynamicHeightContainerdsl.json +++ b/app/client/cypress/fixtures/dynamicHeightContainerdsl.json @@ -13,7 +13,7 @@ "parentRowSpace": 1, "type": "CANVAS_WIDGET", "canExtend": true, - "version": 64, + "version": 69, "minHeight": 1292, "dynamicTriggerPathList": [], "parentColumnSpace": 1, @@ -21,48 +21,42 @@ "leftColumn": 0, "children": [ { - "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "isVisible": true, + "backgroundColor": "#FFFFFF", "widgetName": "Container1", + "containerStyle": "card", "borderColor": "#E0DEDE", - "isCanvas": true, - "displayName": "Container", - "iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg", - "searchTags": [ - "div", - "parent", - "group" - ], - "topRow": 0, - "bottomRow": 40, - "parentRowSpace": 10, - "type": "CONTAINER_WIDGET", - "hideCard": false, - "shouldScrollContents": false, + "borderWidth": "1", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", "animateLoading": true, - "parentColumnSpace": 9.96875, - "leftColumn": 21, - "dynamicBindingPathList": [ - { - "key": "borderRadius" - }, - { - "key": "boxShadow" - } - ], "children": [ { - "boxShadow": "none", + "isVisible": true, "widgetName": "Canvas1", - "displayName": "Canvas", - "topRow": 0, - "bottomRow": 400, - "parentRowSpace": 1, + "version": 1, + "detachFromLayout": true, "type": "CANVAS_WIDGET", - "canExtend": false, "hideCard": true, - "minHeight": 400, + "isDeprecated": false, + "displayName": "Canvas", + "key": "49f4d77rwd", + "containerStyle": "none", + "canExtend": false, + "children": [], + "minHeight": 100, + "widgetId": "tbezx4vcxu", + "renderMode": "CANVAS", + "boxShadow": "none", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "isLoading": false, "parentColumnSpace": 1, + "parentRowSpace": 1, "leftColumn": 0, + "rightColumn": 286.5, + "topRow": 0, + "bottomRow": 100, + "parentId": "57nv0ufxq1", "dynamicBindingPathList": [ { "key": "borderRadius" @@ -70,100 +64,45 @@ { "key": "accentColor" } - ], - "children": [ - { - "isVisible": true, - "minDynamicHeight": 0, - "maxDynamicHeight": 0, - "dynamicHeight": "FIXED", - "animateLoading": true, - "labelTextSize": "0.875rem", - "options": [ - { - "label": "Blue", - "value": "BLUE" - }, - { - "label": "Green", - "value": "GREEN" - }, - { - "label": "Red", - "value": "RED" - } - ], - "defaultSelectedValues": [ - "BLUE" - ], - "isDisabled": false, - "isInline": true, - "isRequired": false, - "labelText": "Label", - "labelPosition": "Left", - "labelAlignment": "left", - "labelWidth": 5, - "widgetName": "CheckboxGroup1", - "version": 2, - "type": "CHECKBOX_GROUP_WIDGET", - "hideCard": false, - "isDeprecated": false, - "displayName": "Checkbox Group", - "key": "y571au2ld4", - "iconSVG": "/static/media/icon.ecb3847950c4515966ef642a32758afb.svg", - "widgetId": "3fcb34jd6s", - "renderMode": "CANVAS", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "isLoading": false, - "parentColumnSpace": 3.42578125, - "parentRowSpace": 10, - "leftColumn": 18, - "rightColumn": 51, - "topRow": 34, - "bottomRow": 38, - "parentId": "u0aukt373p", - "dynamicBindingPathList": [ - { - "key": "accentColor" - }, - { - "key": "borderRadius" - } - ] - } - ], - "key": "05fpu0xal1", - "isDeprecated": false, - "rightColumn": 239.25, - "detachFromLayout": true, - "widgetId": "u0aukt373p", - "accentColor": "{{appsmith.theme.colors.primaryColor}}", - "containerStyle": "none", - "isVisible": true, - "version": 1, - "parentId": "pik2udpz5v", - "renderMode": "CANVAS", - "isLoading": false, - "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}" + ] } ], - "borderWidth": "1", - "key": "bwh1jtvajo", - "backgroundColor": "#FFFFFF", - "isDeprecated": false, - "rightColumn": 45, - "dynamicHeight": "FIXED", - "widgetId": "pik2udpz5v", - "containerStyle": "card", - "isVisible": true, "version": 1, - "parentId": "0", + "minDynamicHeight": 10, + "maxDynamicHeight": 9000, + "dynamicHeight": "AUTO_HEIGHT", + "shouldScrollContents": true, + "searchTags": [ + "div", + "parent", + "group" + ], + "type": "CONTAINER_WIDGET", + "hideCard": false, + "isDeprecated": false, + "displayName": "Container", + "key": "g4phrz9m3l", + "iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg", + "isCanvas": true, + "widgetId": "57nv0ufxq1", "renderMode": "CANVAS", - "isLoading": false, "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", - "maxDynamicHeight": 0, - "minDynamicHeight": 0 + "isLoading": false, + "parentColumnSpace": 11.9375, + "parentRowSpace": 10, + "leftColumn": 20, + "rightColumn": 44, + "topRow": 23, + "bottomRow": 33, + "parentId": "0", + "dynamicBindingPathList": [ + { + "key": "borderRadius" + }, + { + "key": "boxShadow" + } + ] } ] } diff --git a/app/client/cypress/fixtures/dynamicHeightStatboxdsl.json b/app/client/cypress/fixtures/dynamicHeightStatboxdsl.json new file mode 100644 index 0000000000..d1b9422ba4 --- /dev/null +++ b/app/client/cypress/fixtures/dynamicHeightStatboxdsl.json @@ -0,0 +1,281 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1280, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1230, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 69, + "minHeight": 1240, + "parentColumnSpace": 1, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "labelTextSize": "0.875rem", + "boxShadow": "none", + "widgetName": "Statbox1", + "backgroundColor": "white", + "rightColumn": 21, + "dynamicHeight": "FIXED", + "widgetId": "3sii8uhhjs", + "topRow": 17, + "bottomRow": 33, + "parentRowSpace": 10, + "isVisible": true, + "type": "STATBOX_WIDGET", + "parentId": "0", + "isLoading": false, + "parentColumnSpace": 19.8125, + "leftColumn": 5, + "borderRadius": "0px", + "children": [ + { + "labelTextSize": "0.875rem", + "boxShadow": "none", + "widgetName": "Canvas1", + "rightColumn": 317, + "detachFromLayout": true, + "widgetId": "l752czyef7", + "containerStyle": "none", + "topRow": 0, + "bottomRow": 160, + "parentRowSpace": 1, + "isVisible": true, + "canExtend": false, + "type": "CANVAS_WIDGET", + "version": 1, + "parentId": "3sii8uhhjs", + "minHeight": 160, + "isLoading": false, + "parentColumnSpace": 1, + "leftColumn": 0, + "borderRadius": "0px", + "children": [ + { + "boxShadow": "none", + "widgetName": "Text1", + "dynamicPropertyPathList": [ + { + "key": "fontSize" + } + ], + "topRow": 0.5, + "bottomRow": 4.5, + "type": "TEXT_WIDGET", + "overflow": "NONE", + "fontFamily": "System Default", + "dynamicTriggerPathList": [], + "leftColumn": 1.5, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "text": "{{MockApi.data.users[0].id}}", + "labelTextSize": "0.875rem", + "rightColumn": 37.5, + "textAlign": "LEFT", + "dynamicHeight": "FIXED", + "widgetId": "4mtayc9eas", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#999999", + "version": 1, + "parentId": "l752czyef7", + "isLoading": false, + "borderRadius": "0px", + "maxDynamicHeight": 9000, + "fontSize": "0.75rem", + "minDynamicHeight": 4 + }, + { + "boxShadow": "none", + "widgetName": "Text2", + "dynamicPropertyPathList": [ + { + "key": "fontSize" + } + ], + "topRow": 5.5, + "bottomRow": 9.5, + "type": "TEXT_WIDGET", + "overflow": "NONE", + "fontFamily": "System Default", + "leftColumn": 1.5, + "text": "2.6 M", + "labelTextSize": "0.875rem", + "rightColumn": 37.5, + "textAlign": "LEFT", + "dynamicHeight": "FIXED", + "widgetId": "ii2tk6m48f", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1, + "parentId": "l752czyef7", + "isLoading": false, + "borderRadius": "0px", + "maxDynamicHeight": 9000, + "fontSize": "1.5rem", + "minDynamicHeight": 4 + }, + { + "boxShadow": "none", + "widgetName": "Text3", + "dynamicPropertyPathList": [ + { + "key": "fontSize" + } + ], + "topRow": 10, + "bottomRow": 14, + "type": "TEXT_WIDGET", + "overflow": "NONE", + "fontFamily": "System Default", + "leftColumn": 1.5, + "text": "21% more than last month", + "labelTextSize": "0.875rem", + "rightColumn": 37.5, + "textAlign": "LEFT", + "dynamicHeight": "FIXED", + "widgetId": "ptbhksx9p1", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#03B365", + "version": 1, + "parentId": "l752czyef7", + "isLoading": false, + "borderRadius": "0px", + "maxDynamicHeight": 9000, + "fontSize": "0.75rem", + "minDynamicHeight": 4 + }, + { + "labelTextSize": "0.875rem", + "boxShadow": "none", + "widgetName": "IconButton1", + "rightColumn": 61, + "iconName": "arrow-top-right", + "buttonColor": "#03B365", + "dynamicPropertyPathList": [ + { + "key": "borderRadius" + } + ], + "widgetId": "x35ni1hugn", + "topRow": 3, + "bottomRow": 11, + "isVisible": true, + "type": "ICON_BUTTON_WIDGET", + "version": 1, + "parentId": "l752czyef7", + "isLoading": false, + "borderRadius": "9999px", + "leftColumn": 45, + "buttonVariant": "PRIMARY", + "isDisabled": false + } + ] + } + ], + "maxDynamicHeight": 9000, + "minDynamicHeight": 4 + }, + { + "isVisible": true, + "backgroundColor": "#FFFFFF", + "widgetName": "Container1", + "containerStyle": "card", + "borderColor": "#E0DEDE", + "borderWidth": "1", + "boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}", + "animateLoading": true, + "children": [ + { + "isVisible": true, + "widgetName": "Canvas2", + "version": 1, + "detachFromLayout": true, + "type": "CANVAS_WIDGET", + "hideCard": true, + "isDeprecated": false, + "displayName": "Canvas", + "key": "vhu8oytsk7", + "containerStyle": "none", + "canExtend": false, + "children": [], + "minHeight": 580, + "widgetId": "p7wc0hnc0o", + "renderMode": "CANVAS", + "boxShadow": "none", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "accentColor": "{{appsmith.theme.colors.primaryColor}}", + "isLoading": false, + "parentColumnSpace": 1, + "parentRowSpace": 1, + "leftColumn": 0, + "rightColumn": 286.5, + "topRow": 0, + "bottomRow": 580, + "parentId": "q00fefx59g", + "dynamicBindingPathList": [ + { + "key": "borderRadius" + }, + { + "key": "accentColor" + } + ] + } + ], + "version": 1, + "minDynamicHeight": 10, + "maxDynamicHeight": 12, + "dynamicHeight": "FIXED", + "shouldScrollContents": true, + "searchTags": [ + "div", + "parent", + "group" + ], + "type": "CONTAINER_WIDGET", + "hideCard": false, + "isDeprecated": false, + "displayName": "Container", + "key": "fcexgq4024", + "iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg", + "isCanvas": true, + "widgetId": "q00fefx59g", + "renderMode": "CANVAS", + "borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}", + "isLoading": false, + "parentColumnSpace": 11.9375, + "parentRowSpace": 10, + "leftColumn": 22, + "rightColumn": 64, + "topRow": 3, + "bottomRow": 61, + "parentId": "0", + "dynamicBindingPathList": [ + { + "key": "borderRadius" + }, + { + "key": "boxShadow" + } + ], + "dynamicTriggerPathList": [] + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_Limit_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_Limit_spec.js index e5451a30a5..499bc1ef4a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_Limit_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_Limit_spec.js @@ -14,7 +14,7 @@ describe("Dynamic Height Width validation with limits", function() { cy.get("[data-cy='t--auto-height-overlay-handles-min']").trigger( "mouseover", ); - cy.contains("Min-Height: 4 rows"); + cy.contains("Min-Height: 10 rows"); cy.get("[data-cy='t--auto-height-overlay-handles-min']").should( "be.visible", ); @@ -29,7 +29,7 @@ describe("Dynamic Height Width validation with limits", function() { cy.get("[data-cy='t--auto-height-overlay-handles-max']").trigger( "mouseover", ); - cy.contains("Max-Height: 40 rows"); + cy.contains("Max-Height: 12 rows"); //cy.checkMaxDefaultValue(commonlocators.maxHeight,"40") //cy.testJsontext(commonlocators.maxHeight, "60"); cy.get("[data-cy='t--auto-height-overlay-handles-max']").should( diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_spec.js index 033382d8f9..86c2bd1468 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Auto_Height_spec.js @@ -1,4 +1,4 @@ -const dsl = require("../../../../fixtures/dynamicHeightContainerdsl.json"); +const dsl = require("../../../../fixtures/dynamicHeightContainerCheckboxdsl.json"); const commonlocators = require("../../../../locators/commonlocators.json"); describe("Dynamic Height Width validation", function() { @@ -6,9 +6,9 @@ describe("Dynamic Height Width validation", function() { cy.addDsl(dsl); cy.wait(3000); //for dsl to settle cy.openPropertyPane("containerwidget"); - cy.changeLayoutHeight(commonlocators.autoHeight); + //cy.changeLayoutHeight(commonlocators.autoHeight); cy.openPropertyPane("checkboxgroupwidget"); - cy.changeLayoutHeight(commonlocators.autoHeight); + //cy.changeLayoutHeight(commonlocators.autoHeight); cy.get(".t--widget-containerwidget") .invoke("css", "height") .then((height) => { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Form_With_SwitchGroup_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Form_With_SwitchGroup_spec.js index d7407f2e70..1d98ca2d30 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Form_With_SwitchGroup_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Form_With_SwitchGroup_spec.js @@ -85,7 +85,7 @@ describe("Dynamic Height Width validation", function() { cy.get(".t--widget-propertypane-toggle") .first() .click({ force: true }); - cy.changeLayoutHeight(commonlocators.autoHeightWithLimits); + //cy.changeLayoutHeight(commonlocators.autoHeightWithLimits); //cy.checkMinDefaultValue(commonlocators.minHeight,"4") //cy.checkMaxDefaultValue(commonlocators.maxHeight,"24") cy.changeLayoutHeight(commonlocators.autoHeight); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Multiple_Container_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Multiple_Container_spec.js index dac1c929a3..e62feac13b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Multiple_Container_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Multiple_Container_spec.js @@ -2,8 +2,10 @@ const dsl = require("../../../../fixtures/multipleContainerdsl.json"); const commonlocators = require("../../../../locators/commonlocators.json"); describe("Dynamic Height Width validation for multiple container", function() { - it("Validate change in auto height width with multiple containers", function() { + before(() => { cy.addDsl(dsl); + }); + it("Validate change in auto height width with multiple containers", function() { cy.wait(3000); //for dsl to settle cy.openPropertyPaneWithIndex("containerwidget", 0); cy.changeLayoutHeight(commonlocators.fixed); @@ -14,6 +16,7 @@ describe("Dynamic Height Width validation for multiple container", function() { cy.openPropertyPane("checkboxgroupwidget"); cy.changeLayoutHeight(commonlocators.fixed); cy.changeLayoutHeight(commonlocators.autoHeight); + cy.wait(2000); cy.get(".t--widget-containerwidget") .eq(0) .invoke("css", "height") @@ -26,15 +29,16 @@ describe("Dynamic Height Width validation for multiple container", function() { .eq(2) .invoke("css", "height") .then((iheight) => { - cy.get(commonlocators.addOption).click({ force: true }); cy.get(".t--widget-checkboxgroupwidget") .invoke("css", "height") .then((checkboxheight) => { + cy.get(commonlocators.addOption).click({ force: true }); cy.wait("@updateLayout").should( "have.nested.property", "response.body.responseMeta.status", 200, ); + cy.wait(3000); cy.get(".t--widget-checkboxgroupwidget") .invoke("css", "height") .then((newcheckboxheight) => { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Visibility_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Visibility_spec.js index 9053cbf227..17c2fac37c 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Visibility_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DynamicHeight/DynamicHeight_Visibility_spec.js @@ -1,52 +1,52 @@ const commonlocators = require("../../../../locators/commonlocators.json"); const dsl = require("../../../../fixtures/invisibleWidgetdsl.json"); -describe("Dynamic Height Width validation for Visibility", function () { - before(() => { - cy.addDsl(dsl); - }); - it("Validating visbility/invisiblity of widget with dynamic height feature", function () { - //changing the Text Name and verifying - cy.wait(3000); - cy.openPropertyPane("containerwidget"); - cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight); - cy.openPropertyPaneWithIndex("inputwidgetv2", 0); - cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight); - cy.openPropertyPaneWithIndex("inputwidgetv2", 1); - cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight); +describe("Dynamic Height Width validation for Visibility", function() { + before(() => { + cy.addDsl(dsl); + }); + it("Validating visbility/invisiblity of widget with dynamic height feature", function() { + //changing the Text Name and verifying + cy.wait(3000); + cy.openPropertyPane("containerwidget"); + cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight); + cy.openPropertyPaneWithIndex("inputwidgetv2", 0); + cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight); + cy.openPropertyPaneWithIndex("inputwidgetv2", 1); + cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight); + cy.get(".t--widget-containerwidget") + .invoke("css", "height") + .then((theight) => { + cy.get(commonlocators.checkboxIndicator).click({ force: true }); cy.get(".t--widget-containerwidget") - .invoke("css", "height") - .then((theight) => { - cy.get(commonlocators.checkboxIndicator).click({ force: true }); - cy.get(".t--widget-containerwidget") - .invoke("css", "height") - .then((tnewheight) => { - expect(theight).to.equal(tnewheight); - cy.get("label:Contains('On')").should("not.be.enabled"); - }); - }); - cy.PublishtheApp(); + .invoke("css", "height") + .then((tnewheight) => { + expect(theight).to.equal(tnewheight); + cy.get("label:Contains('On')").should("not.be.enabled"); + }); + }); + cy.PublishtheApp(); + cy.get(".t--widget-containerwidget") + .invoke("css", "height") + .then((theight) => { + cy.get(".bp3-control-indicator").click({ force: true }); + cy.wait(2000); cy.get(".t--widget-containerwidget") - .invoke("css", "height") - .then((theight) => { - cy.get(".bp3-control-indicator").click({ force: true }); - cy.wait(2000); - cy.get(".t--widget-containerwidget") - .invoke("css", "height") - .then((tnewheight) => { - expect(theight).to.not.equal(tnewheight); - cy.get("label:Contains('On')").should("not.exist"); - cy.get("label:Contains('Off')").should("be.visible"); - cy.get(".bp3-control-indicator").click({ force: true }); - cy.wait(2000); - cy.get(".t--widget-containerwidget") - .invoke("css", "height") - .then((tonheight) => { - expect(tonheight).to.not.equal(tnewheight); - cy.get("label:Contains('Off')").should("not.exist"); - cy.get("label:Contains('On')").should("be.visible"); - }); - }); - }); - }); + .invoke("css", "height") + .then((tnewheight) => { + expect(theight).to.not.equal(tnewheight); + cy.get("label:Contains('On')").should("not.exist"); + cy.get("label:Contains('Off')").should("be.visible"); + cy.get(".bp3-control-indicator").click({ force: true }); + cy.wait(2000); + cy.get(".t--widget-containerwidget") + .invoke("css", "height") + .then((tonheight) => { + expect(tonheight).to.not.equal(tnewheight); + cy.get("label:Contains('Off')").should("not.exist"); + cy.get("label:Contains('On')").should("be.visible"); + }); + }); + }); + }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js index dd58a820b5..3729deac88 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js @@ -1,7 +1,8 @@ describe("Visual regression tests", () => { // for any changes in UI, update the screenshot in snapshot folder, to do so: // 1. Delete the required screenshot which you want to update - // 2. Run test in headless mode with any browser (to maintain same resolution in CI) + // 2. Run test in headless mode with chrome (to maintain same resolution in CI) + // command: "npx cypress run --spec cypress/integration/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js --browser chrome" // 3. New screenshot will be generated in the snapshot folder it("Verify SwitchGroup inline enable/disbale", () => { @@ -18,7 +19,7 @@ describe("Visual regression tests", () => { //Unchecking & verify snap cy.get(".t--property-control-inline input") .uncheck({ force: true }) - .wait(200) + .wait(2000) .should("not.be.checked"); cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( "inlineDisabled", @@ -27,7 +28,7 @@ describe("Visual regression tests", () => { //Checking again & verify snap cy.get(".t--property-control-inline input") .check({ force: true }) - .wait(200) + .wait(2000) .should("be.checked"); cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( @@ -37,7 +38,7 @@ describe("Visual regression tests", () => { //Unchecking again & verify snap cy.get(".t--property-control-inline input") .uncheck({ force: true }) - .wait(200) + .wait(2000) .should("not.be.checked"); // taking screenshot of app home page in edit mode cy.get("[data-testid=switchgroup-container]").matchImageSnapshot( diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/Others/Statbox_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/Others/Statbox_spec.js index 879a282d55..2e8bcaf676 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/Others/Statbox_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Widgets/Others/Statbox_spec.js @@ -1,4 +1,5 @@ const dsl = require("../../../../../fixtures/StatboxDsl.json"); +const dsl1 = require("../../../../../fixtures/dynamicHeightStatboxdsl.json"); const explorer = require("../../../../../locators/explorerlocators.json"); const data = require("../../../../../fixtures/example.json"); const widgetsPage = require("../../../../../locators/Widgets.json"); @@ -87,9 +88,10 @@ describe("Statbox Widget Functionality", function() { }); it("5. Verify Statbox can be placed inside another widget", () => { + cy.addDsl(dsl1); cy.get(explorer.addWidget).click(); // placing statbox widget inside container widget - cy.dragAndDropToCanvas("containerwidget", { x: 500, y: 300 }); + //cy.dragAndDropToCanvas("containerwidget", { x: 500, y: 300 }); cy.dragAndDropToWidget("statboxwidget", "containerwidget", { x: 100, y: 100, diff --git a/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js/inlineDisabled.snap.png b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js/inlineDisabled.snap.png index bb646fa2d0d7734c6fc24d2657f0a2f8b25ba162..34696421e14f224772660ed241ad032ce1a09812 100644 GIT binary patch literal 4689 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 literal 2086 zcmbuAX*3&J0>>Fj5E2ziEfu`l8kI^B)n_EJHANpuN>NK|n|c%}Cbd*0h}cTCR4}Nm z)Y?>IX=^PiQdFZ9B|~&-X=rV=ygYNx%sKOQzWnb!=iYPgIluF}|4Y5(U?VMgTvA9# zNZQU8<0K>`Y#^8;0Ahb8X-u#nzHEoF#6<}&cSzkFrKrBs8O zJO}Fcy%VdsWK0LW-+o;sf|a#GIz$7l)bvEo^JwuVp5YoUs?N`n$JKiz7-(-NTA7!t z6uS7nvHc^&L0rT^>q0uW5@8v+$DZL`lSu58C4)OL5J6o3pSaI*8(;?PmUVL}4?Vpn zQuDg27dOsD?Nc6tQOPbk04TZtFe>TR^XaPQtv>R2PeS%m7(5gu+~m)~;PEAeZp;+M zFCoQW&9dW=RAwZ**Qdd2+^sdE?Cpt)782-rH)f?JTp?RqUV{wgJ0a7!_N-4~qd4n~ zfzmHqp}_@L2P@mmd)-YXyR;|u6wL#`A+@gdtm)$m7SA#tYl$1tg1L*s*1`Kz#D!1i z^Ld4&tab(iG81}i``VkiFr+LhIZB7#yA`_aj)(vfs&fhh15?-C2b1zmh^9@dy57&WS*?j6Oo7E3?^N8J9T1NnQ!%}HXXewETM4Q-A}cFP04%DC z-uvnH3hzUHMHuUTwW0a500|fihKX@)7q=g^wY7a+e|z)c_f-xE&3@MOg;RH;?$yqj ziV_{kE2gPnR5z+Pq4w)yOZuPTpmnqZ3_LP?OSP*5eK5P1cH*YSs~L86UAu#+O8Lv; z_^jsrMC}6~VD?D|FV3r%UfgofFhUw_HE&Th)eJ&!e4EAL2ql5XQGj9mgH4maYc^kO zP0RlAuQA&1^ZDCbCnj^l+3k;8rUV3fQ8H&m&mo(*QAt3c0S=u`ydecOv`y`>g={1N(W=`TQ%oFg`bAj7sUMG7JfIYz$kb z>*#YF2(_y0ZsQ00`)P=Ldt-uqQ*TyYsB((LMS{*M%Cxz+8bHa z?h73vKuoj7Jpve4?NGDgF_K;5ey*T@fMFy!b@$gaf3@GWR89sf&?rkwD!~QDX^zby zHUK`i^xf?8SysSt_&UU_Z?GZU%#|5oPLa_tt8ts^&f8gPV)rS*?+!uii+U#*HnMT@o+`SKR3L9TH=DOuQf)5h5ry4b zssX@#^*kcJ_sKpub(IVS1L|WYjp+v3)rAK}1;|~NcQg!!p>%ogdt6Sc{i+!Jh$O=E zqhmiVz(oHd99)DH32{|=2!W`R7pEa+D(2vmY6O-wr(!zC`R1jKCQ2 zC-kbp!BZQY4|AJ8Lrqn*w6wr7Nz@Aw%x~M#m>7mX=(l##o~S*?b=_J*AOMui)FJi_ zVYSqzrD4RJNVHTUT`Gu9-TS%GunWQ}A=jc+WW*C?HEkN_OEZ$!QkB`gX{&Mo(SV?! z>th4*7+-&$VZdkg!l-EEuSFoVhllEPf!&?6xEGOjjsi&Zffe>-)KYv1b;J%4yxCKhndmRxF+k@et#HSWd@eVHT? zT2E)yGX_HzC}wA8X9@6@kyz(hytpGHA~yLBQBZdSF)^u0#NXDr8;RDRQ47}Y&$}~P z^-eA28y=s@IIYU#J>_u8k#gPXph`Gp4tlj zNXU*1uAixXPrugD@;5>MuTm~(LdUF diff --git a/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js/inlineEnabled.snap.png b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js/inlineEnabled.snap.png index 8b4040961299b8f801554d4106473525a4746eaa..02c692a097432f50f0a1803c4f412e2021d517ba 100644 GIT binary patch delta 4128 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 Fe*%qqCrDRX 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 { Cypress.Commands.add("changeLayoutHeight", (locator) => { cy.get(".t--property-control-height .remixicon-icon") - .should("be.visible") + .scrollIntoView() .click({ force: true }); cy.get(locator).click({ force: true }); cy.wait("@updateLayout").should( @@ -1614,7 +1614,7 @@ Cypress.Commands.add("changeLayoutHeight", (locator) => { Cypress.Commands.add("changeLayoutHeightWithoutWait", (locator) => { cy.get(".t--property-control-height .remixicon-icon") - .should("be.visible") + .scrollIntoView() .click({ force: true }); cy.get(locator).click({ force: true }); }); diff --git a/app/client/src/components/autoHeight/AutoHeightContainer.tsx b/app/client/src/components/autoHeight/AutoHeightContainer.tsx index 5c66e9ae48..a9be60af32 100644 --- a/app/client/src/components/autoHeight/AutoHeightContainer.tsx +++ b/app/client/src/components/autoHeight/AutoHeightContainer.tsx @@ -78,7 +78,10 @@ export default function AutoHeightContainer({ expectedHeight / GridDefaults.DEFAULT_GRID_ROW_HEIGHT, ); - const backgroundColor = widgetProps?.backgroundColor; + const backgroundColor = + widgetProps?.type === "TEXT_WIDGET" + ? widgetProps?.backgroundColor + : undefined; return ( ` +interface StyledAutoHeightOverlayProps { + layerIndex: number; + isHidden: boolean; +} + +const StyledAutoHeightOverlay = styled.div` width: 100%; height: 100%; position: absolute; - z-index: 3; + z-index: ${(props) => props.layerIndex}; pointer-events: none; display: ${(props) => (props.isHidden ? "none" : "block")}; `; @@ -252,9 +258,12 @@ const AutoHeightOverlay: React.FC = memo( topRow, }); + const { autoHeightWithLimitsOverlay } = React.useContext(LayersContext); + return ( { // avoid DropTarget handleFocus e.stopPropagation(); diff --git a/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.test.tsx b/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.test.tsx index a11850f2c8..9aba34b0a0 100644 --- a/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.test.tsx +++ b/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.test.tsx @@ -10,13 +10,13 @@ describe("", () => { const tree = renderer .create() .toJSON(); - expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale(1)"); + expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale( 1 )"); }); it("should have scale style set to 1.67 when isDragging is true", () => { const tree = renderer .create() .toJSON(); - expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale(1.67)"); + expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale( 1.67 )"); }); }); diff --git a/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.tsx b/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.tsx index a8b7b53c9a..59e41d70b3 100644 --- a/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.tsx +++ b/app/client/src/components/autoHeightOverlay/ui/AutoHeightLimitHandleDot.tsx @@ -1,5 +1,5 @@ import styled from "styled-components"; -import { OVERLAY_COLOR } from "../constants"; +import { OVERLAY_COLOR, OVERLAY_HANDLE_DOT_DRAGGING_SCALE } from "../constants"; interface AutoHeightLimitHandleDotProps { isDragging: boolean; @@ -12,7 +12,9 @@ const AutoHeightLimitHandleDot = styled.div` width: 7px; height: 7px; transform: translateX(-50%) - scale(${(props) => (props.isDragging ? "1.67" : "1")}); + scale( + ${(props) => (props.isDragging ? OVERLAY_HANDLE_DOT_DRAGGING_SCALE : "1")} + ); border: 1px solid ${OVERLAY_COLOR}; background-color: ${OVERLAY_COLOR}; box-shadow: 0px 0px 0px 2px white; diff --git a/app/client/src/constants/DefaultTheme.tsx b/app/client/src/constants/DefaultTheme.tsx index 51acbcea68..970ca47a7d 100644 --- a/app/client/src/constants/DefaultTheme.tsx +++ b/app/client/src/constants/DefaultTheme.tsx @@ -320,17 +320,18 @@ export const BlueprintRadioSwitchGroupTransform = css<{ optionCount: number; }>` width: 100%; + height: 100%; - ${({ alignment, inline, optionCount }) => ` - display: ${ - inline ? "inline-flex" : alignment === Alignment.RIGHT ? "block" : "flex" - }; + ${({ inline, optionCount }) => ` + display: ${inline ? "inline-flex" : "flex"}; flex-direction: ${inline ? "row" : "column"}; align-items: ${inline ? "center" : "flex-start"}; ${inline && "flex-wrap: wrap"}; justify-content: ${ optionCount > 1 ? `space-between` : inline ? `flex-start` : `center` }; + gap: 10px; + flex-grow: 1; `} ${BlueprintControlTransform}; @@ -341,42 +342,17 @@ export const BlueprintRadioSwitchGroupTransform = css<{ } return "flex"; }}; + width: ${({ alignment, inline }) => { + if (alignment === Alignment.RIGHT) { + return inline ? "auto" : "100%"; + } + return "auto"; + }}; align-items: center; border: 1px solid transparent; color: ${Colors.GREY_10}; line-height: 16px; - min-height: ${({ alignment }) => - alignment === Alignment.RIGHT ? 23 : 30}px; - margin-top: ${({ alignment }) => (alignment === Alignment.RIGHT ? 7 : 0)}px; - margin-bottom: ${({ - alignment, - height, - inline, - labelPosition, - optionCount, - }) => { - if ( - alignment === Alignment.RIGHT && - !inline && - optionCount > 1 && - height - ) { - return Math.max( - (height - - (labelPosition === LabelPosition.Left ? 0 : 35) - - optionCount * 31) / - (optionCount - 1), - 8, - ); - } else { - return 0; - } - }}px; - - &:last-child { - margin-bottom: 0; - } .bp3-control-indicator { margin-top: 0; border: 1px solid ${Colors.GREY_5}; diff --git a/app/client/src/constants/Layers.tsx b/app/client/src/constants/Layers.tsx index 83b4df18a7..8ffbd8540c 100644 --- a/app/client/src/constants/Layers.tsx +++ b/app/client/src/constants/Layers.tsx @@ -57,6 +57,8 @@ export const Layers = { evaluationPopper: Indices.Layer3, concurrentEditorWarning: Indices.Layer2, manualUpgrade: Indices.Layer10, + + autoHeightWithLimitsOverlay: Indices.Layer3, }; export const tailwindLayers = { diff --git a/app/client/src/constants/WidgetConstants.tsx b/app/client/src/constants/WidgetConstants.tsx index bfa1752b21..8e767691e0 100644 --- a/app/client/src/constants/WidgetConstants.tsx +++ b/app/client/src/constants/WidgetConstants.tsx @@ -167,4 +167,5 @@ export const DEFAULT_FONT_SIZE = THEMEING_TEXT_SIZES.base; export const WidgetHeightLimits = { MAX_HEIGHT_IN_ROWS: 9000, MIN_HEIGHT_IN_ROWS: 4, + MIN_CANVAS_HEIGHT_IN_ROWS: 10, }; diff --git a/app/client/src/pages/AppViewer/index.tsx b/app/client/src/pages/AppViewer/index.tsx index a770a6b90f..3ccf9c8b35 100644 --- a/app/client/src/pages/AppViewer/index.tsx +++ b/app/client/src/pages/AppViewer/index.tsx @@ -239,6 +239,11 @@ function AppViewer(props: Props) { [updateWidgetAutoHeightAction, dispatch], ); + const checkContainersForAutoHeightCallback = useCallback( + () => dispatch(checkContainersForAutoHeightAction()), + [checkContainersForAutoHeightAction], + ); + return ( ) { shouldReplay: false, }), ); + if (isPropertyUpdate) { - yield put(generateAutoHeightLayoutTreeAction(true, false)); yield call(openPropertyPaneSaga, replay); } if (!isPropertyUpdate) { yield call(postUndoRedoSaga, replay); } + yield put(generateAutoHeightLayoutTreeAction(true, false)); break; } case ENTITY_TYPE.ACTION: diff --git a/app/client/src/sagas/autoHeightSagas/containers.ts b/app/client/src/sagas/autoHeightSagas/containers.ts index e5a11d1e9b..59c0bf2cce 100644 --- a/app/client/src/sagas/autoHeightSagas/containers.ts +++ b/app/client/src/sagas/autoHeightSagas/containers.ts @@ -1,18 +1,13 @@ import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import { GridDefaults } from "constants/WidgetConstants"; -import { groupBy } from "lodash"; import log from "loglevel"; import { AutoHeightLayoutTreeReduxState } from "reducers/entityReducers/autoHeightReducers/autoHeightLayoutTreeReducer"; -import { CanvasLevelsReduxState } from "reducers/entityReducers/autoHeightReducers/canvasLevelsReducer"; import { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; import { call, put, select } from "redux-saga/effects"; -import { shouldWidgetsCollapse } from "./helpers"; +import { getMinHeightBasedOnChildren, shouldWidgetsCollapse } from "./helpers"; import { getWidgets } from "sagas/selectors"; import { getCanvasHeightOffset } from "selectors/editorSelectors"; -import { - getAutoHeightLayoutTree, - getCanvasLevelMap, -} from "selectors/autoHeightSelectors"; +import { getAutoHeightLayoutTree } from "selectors/autoHeightSelectors"; import { FlattenedWidgetProps } from "widgets/constants"; import { getWidgetMaxAutoHeight, @@ -20,6 +15,8 @@ import { isAutoHeightEnabledForWidget, } from "widgets/WidgetUtils"; import { getChildOfContainerLikeWidget } from "./helpers"; +import { getDataTree } from "selectors/dataTreeSelectors"; +import { DataTree, DataTreeWidget } from "entities/DataTree/dataTreeFactory"; export function* dynamicallyUpdateContainersSaga() { const start = performance.now(); @@ -27,132 +24,158 @@ export function* dynamicallyUpdateContainersSaga() { const stateWidgets: CanvasWidgetsReduxState = yield select(getWidgets); const canvasWidgets: FlattenedWidgetProps[] | undefined = Object.values( stateWidgets, - ).filter((widget: FlattenedWidgetProps) => widget.type === "CANVAS_WIDGET"); - const canvasLevelMap: CanvasLevelsReduxState = yield select( - getCanvasLevelMap, - ); + ).filter((widget: FlattenedWidgetProps) => { + const isCanvasWidget = widget.type === "CANVAS_WIDGET"; + const parent = widget.parentId ? stateWidgets[widget.parentId] : undefined; + if (parent?.type === "LIST_WIDGET") return false; + if (!parent) return false; + return isCanvasWidget; + }); const dynamicHeightLayoutTree: AutoHeightLayoutTreeReduxState = yield select( getAutoHeightLayoutTree, ); - const groupedByCanvasLevel = groupBy( - canvasWidgets, - (widget) => canvasLevelMap[widget.widgetId], - ); - - const levels = Object.keys(groupedByCanvasLevel) - .map((level) => parseInt(level, 10)) - .sort((a, b) => b - a); - const updates: Record = {}; const shouldCollapse: boolean = yield call(shouldWidgetsCollapse); - for (const level of levels) { - const canvasWidgetsAtThisLevel = groupedByCanvasLevel[`${level}`]; - for (const canvasWidget of canvasWidgetsAtThisLevel) { - if (canvasWidget.parentId) { - const parentContainerWidget = stateWidgets[canvasWidget.parentId]; + for (const canvasWidget of canvasWidgets) { + if (canvasWidget.parentId) { + // The parent widget of this canvas widget + const parentContainerWidget = stateWidgets[canvasWidget.parentId]; - let bottomRow, topRow, originalBottomRow, originalTopRow; - if (dynamicHeightLayoutTree[parentContainerWidget.widgetId]) { - const layoutNode = - dynamicHeightLayoutTree[parentContainerWidget.widgetId]; - bottomRow = layoutNode.bottomRow; - topRow = layoutNode.topRow; - originalBottomRow = layoutNode.originalBottomRow; - originalTopRow = layoutNode.originalTopRow; - } else { - bottomRow = parentContainerWidget.bottomRow; - topRow = parentContainerWidget.topRow; + // Skip this whole process if the parent is collapsed: Process: + // Get the DataTree + const dataTree: DataTree = yield select(getDataTree); + // Get this parentContainerWidget from the DataTree + const dataTreeWidget = dataTree[parentContainerWidget.widgetName]; + // If the widget exists, is not visible and we can collapse widgets + if ( + dataTreeWidget && + (dataTreeWidget as DataTreeWidget).isVisible !== true && + shouldCollapse + ) + continue; + + let bottomRow, topRow; + // If the parent exists in the layout tree + if (dynamicHeightLayoutTree[parentContainerWidget.widgetId]) { + // Get the tree node for the parent + const layoutNode = + dynamicHeightLayoutTree[parentContainerWidget.widgetId]; + // Get all the dimensions from the tree node + bottomRow = layoutNode.bottomRow; + topRow = layoutNode.topRow; + } else { + // If it doesn't exist in the layout tree + // It is most likely a Modal Widget + // Use the dimensions as they exist in the widget. + bottomRow = parentContainerWidget.bottomRow; + topRow = parentContainerWidget.topRow; + } + + // If this is a Modal widget or some other widget + // which is detached from layout + // use the value 0, as the starting point. + if ( + parentContainerWidget.detachFromLayout && + parentContainerWidget.height + ) { + topRow = 0; + } + + if (isAutoHeightEnabledForWidget(parentContainerWidget)) { + // Get the child we need to consider + // For a container widget, it will be the child canvas + // For a tabs widget, it will be the currently open tab's canvas + const childWidgetId: + | string + | undefined = yield getChildOfContainerLikeWidget( + parentContainerWidget, + ); + + // This can be different from the canvas widget in consideration + // For example, if this canvas widget in consideration + // is not the selected tab's canvas in a tabs widget + // we don't have to consider it at all + if (childWidgetId !== canvasWidget.widgetId) continue; + + // Get the boundaries for possible min and max dynamic height. + const minDynamicHeightInRows = getWidgetMinAutoHeight( + parentContainerWidget, + ); + const maxDynamicHeightInRows = getWidgetMaxAutoHeight( + parentContainerWidget, + ); + + // Default to the min height expected. + let maxBottomRow = minDynamicHeightInRows; + + // For the child Canvas, use the value in pixels. + let canvasBottomRow = maxBottomRow; + + // If this canvas has children + // we need to consider the bottom most child for the height + if ( + Array.isArray(canvasWidget.children) && + canvasWidget.children.length > 0 + ) { + let maxBottomRowBasedOnChildren: number = yield getMinHeightBasedOnChildren( + canvasWidget.widgetId, + {}, + true, + dynamicHeightLayoutTree, + ); + // Add a canvas extension offset + maxBottomRowBasedOnChildren += GridDefaults.CANVAS_EXTENSION_OFFSET; + // Set the canvas bottom row as a new variable with a new reference + canvasBottomRow = maxBottomRowBasedOnChildren + 0; + // For widgets like Tabs Widget, some of the height is occupied by the + // tabs themselves, the child canvas as a result has less number of rows available + // To accommodate for this, we need to increase the new height by the offset amount. + const canvasHeightOffset: number = getCanvasHeightOffset( + parentContainerWidget.type, + parentContainerWidget, + ); + + // Add the offset to the total height of the parent widget + maxBottomRowBasedOnChildren += canvasHeightOffset; + + // Get the larger value between the minDynamicHeightInRows and bottomMostRowForChild + maxBottomRow = Math.max(maxBottomRowBasedOnChildren, maxBottomRow); } - if (isAutoHeightEnabledForWidget(parentContainerWidget)) { - const childWidgetId: - | string - | undefined = yield getChildOfContainerLikeWidget( - parentContainerWidget, - ); - if (childWidgetId !== canvasWidget.widgetId) continue; - let maxBottomRow = bottomRow - topRow; - if ( - parentContainerWidget.detachFromLayout && - parentContainerWidget.height - ) { - topRow = 0; - bottomRow = Math.ceil( - parentContainerWidget.height / - GridDefaults.DEFAULT_GRID_ROW_HEIGHT, - ); + // The following makes sure we stay within bounds + // If the new height is below the min threshold + if (maxBottomRow < minDynamicHeightInRows) { + maxBottomRow = minDynamicHeightInRows; + } + // If the new height is above the max threshold + if (maxBottomRow > maxDynamicHeightInRows) { + maxBottomRow = maxDynamicHeightInRows; + } - maxBottomRow = bottomRow; - } + canvasBottomRow = + Math.max(maxBottomRow, canvasBottomRow) * + GridDefaults.DEFAULT_GRID_ROW_HEIGHT; - let canvasBottomRow = canvasWidget.bottomRow; - - if ( - Array.isArray(canvasWidget.children) && - canvasWidget.children.length > 0 - ) { - maxBottomRow = canvasWidget.children - .filter((widgetId) => !stateWidgets[widgetId].detachFromLayout) - .reduce((prev: number, next: string) => { - if (dynamicHeightLayoutTree[next].bottomRow > prev) - return dynamicHeightLayoutTree[next].bottomRow; - return prev; - }, 0); - maxBottomRow += GridDefaults.CANVAS_EXTENSION_OFFSET; - canvasBottomRow = maxBottomRow + 0; - - // For widgets like Tabs Widget, some of the height is occupied by the - // tabs themselves, the child canvas as a result has less number of rows available - // To accommodate for this, we need to increase the new height by the offset amount. - const canvasHeightOffset: number = getCanvasHeightOffset( - parentContainerWidget.type, - parentContainerWidget, - ); - - maxBottomRow += canvasHeightOffset; - } else if ( - !shouldCollapse && - topRow === bottomRow && - originalBottomRow !== undefined && - originalTopRow !== undefined - ) { - maxBottomRow = originalBottomRow - originalTopRow; - } - - // Get the boundaries for possible min and max dynamic height. - const minDynamicHeightInRows = getWidgetMinAutoHeight( - parentContainerWidget, - ); - const maxDynamicHeightInRows = getWidgetMaxAutoHeight( - parentContainerWidget, - ); - - // If the new height is below the min threshold - if (maxBottomRow < minDynamicHeightInRows) { - maxBottomRow = minDynamicHeightInRows; - } - // If the new height is above the max threshold - if (maxBottomRow > maxDynamicHeightInRows) { - maxBottomRow = maxDynamicHeightInRows; - } - - if ( - maxBottomRow !== bottomRow - topRow || - canvasBottomRow !== canvasWidget.bottomRow - ) { - if (!updates.hasOwnProperty(parentContainerWidget.widgetId)) { - updates[parentContainerWidget.widgetId] = - maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT; - } + // If we have a new height to set and + // If the canvas for some reason doesn't have the correct bottomRow + if ( + maxBottomRow !== bottomRow - topRow || + canvasBottomRow !== canvasWidget.bottomRow + ) { + if (!updates.hasOwnProperty(parentContainerWidget.widgetId)) { + updates[parentContainerWidget.widgetId] = + maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT; } } } } } + log.debug("Dynamic Height: Container Updates", { updates }); + if (Object.keys(updates).length > 0) { // TODO(abhinav): Make sure there are no race conditions or scenarios where these updates are not considered. for (const widgetId in updates) { diff --git a/app/client/src/sagas/autoHeightSagas/helpers.ts b/app/client/src/sagas/autoHeightSagas/helpers.ts index 192cb92f9d..b0d4003b9a 100644 --- a/app/client/src/sagas/autoHeightSagas/helpers.ts +++ b/app/client/src/sagas/autoHeightSagas/helpers.ts @@ -56,21 +56,28 @@ export function* getMinHeightBasedOnChildren( ignoreParent = false, tree: AutoHeightLayoutTreeReduxState, ) { + // Starting with no height let minHeightInRows = 0; + + // Should we be able to collapse widgets const shouldCollapse: boolean = yield shouldWidgetsCollapse(); + // Get all widgets in the DSL const stateWidgets: CanvasWidgetsReduxState = yield select(getWidgets); const { children = [], parentId } = stateWidgets[widgetId]; + // If we need to consider the parent height if (parentId && !ignoreParent) { - let parentHeightInRows = - stateWidgets[parentId].bottomRow - stateWidgets[parentId].topRow; + // Get the parentHeight in rows + let parentHeightInRows = tree[parentId].bottomRow - tree[parentId].topRow; + + // If the parent has changed so far. if (changesSoFar.hasOwnProperty(parentId)) { parentHeightInRows = changesSoFar[parentId].bottomRow - changesSoFar[parentId].topRow; } + // The canvas will be an extension smaller than the parent? minHeightInRows = parentHeightInRows - GridDefaults.CANVAS_EXTENSION_OFFSET; - // If the canvas is empty return the parent's height in rows, without // the canvas extension offset if (!children.length) { @@ -85,13 +92,17 @@ export function* getMinHeightBasedOnChildren( // We ignore widgets like ModalWidget which don't occupy parent's space. // detachFromLayout helps us identify such widgets if (detachFromLayout) continue; + + // Get the child widget's dimenstions from the tree const { bottomRow, topRow } = tree[childWidgetId]; + // If this child has changed so far during computations if (changesSoFar.hasOwnProperty(childWidgetId)) { const collapsing = changesSoFar[childWidgetId].bottomRow === changesSoFar[childWidgetId].topRow; + // If this child is collapsing, don't consider it if (!(shouldCollapse && collapsing)) minHeightInRows = Math.max( minHeightInRows, @@ -99,6 +110,7 @@ export function* getMinHeightBasedOnChildren( ); // If we need to get the existing bottomRow from the state } else { + // If this child is to collapse, don't consider it. if (!(shouldCollapse && bottomRow === topRow)) minHeightInRows = Math.max(minHeightInRows, bottomRow); } diff --git a/app/client/src/sagas/autoHeightSagas/widgets.ts b/app/client/src/sagas/autoHeightSagas/widgets.ts index 17bcb0ab7e..63c935ff5c 100644 --- a/app/client/src/sagas/autoHeightSagas/widgets.ts +++ b/app/client/src/sagas/autoHeightSagas/widgets.ts @@ -34,6 +34,21 @@ import { CanvasLevelsReduxState } from "reducers/entityReducers/autoHeightReduce import { getCanvasLevelMap } from "selectors/autoHeightSelectors"; import { getLayoutTree } from "./layoutTree"; +/* TODO(abhinav) + hasScroll is no longer needed, as the only way we will be computing for hasScroll, is when we get the updates + from the Container computations saga. In container computations, we also compute the inner canvas height. So, + this becomes a duplicate run of pretty much the same code. + + In most cases, when we run the getMinHeightBasedOnChildren, we add the CANVAS_EXTENSION_OFFSET and the offset + from the widget configuration. This means that we can DRY this by moving them into the getMinHeightBasedOnChildren function + + The computations we do when a widget changes for its parent, is pretty much the same as the ones we do in container + computations saga, so we can potentially re-use that code. + + Adding to widgetsToUpdate can be done using one function and shrink this saga by a large amount + + + /** * Saga to update a widget's auto height * When a widget changes in height, it must do the following @@ -273,6 +288,36 @@ export function* updateWidgetAutoHeightSaga() { const parentContainerLikeWidget: FlattenedWidgetProps = stateWidgets[parentCanvasWidget.parentId]; + let minCanvasHeightInRows: number = yield getMinHeightBasedOnChildren( + parentCanvasWidget.widgetId, + changesSoFar, + true, + dynamicHeightLayoutTree, + ); + + // Add extra rows, this is to accommodate for padding and margins in the parent + minCanvasHeightInRows += GridDefaults.CANVAS_EXTENSION_OFFSET; + // Setting this in a variable, as this will be the total scroll height in the canvas. + const minCanvasHeightInPixels = + minCanvasHeightInRows * GridDefaults.DEFAULT_GRID_ROW_HEIGHT; + + // We need to make sure that the canvas widget doesn't have + // any extra scroll, to this end, we need to add the `minHeight` update + // for the canvas widgets. Canvas Widgets are never updated in other flows + // As they simply take up whatever space the parent has, but this doesn't effect + // the `minHeight`, which leads to scroll if the `minHeight` is a larger value. + // Also, for canvas widgets, the values are in pure pixels instead of rows. + widgetsToUpdate[parentCanvasWidgetId] = [ + { + propertyPath: "bottomRow", + propertyValue: minCanvasHeightInPixels, + }, + { + propertyPath: "minHeight", + propertyValue: minCanvasHeightInPixels, + }, + ]; + // Widgets need to consider changing heights, only if they have dynamic height // enabled. if (isAutoHeightEnabledForWidget(parentContainerLikeWidget)) { @@ -282,21 +327,11 @@ export function* updateWidgetAutoHeightSaga() { parentContainerLikeWidget, ); - // Get the array of children ids. - // This cannot be [], because we came to this point due to an update - // caused by one of the children. - - let minPossibleHeight: number = yield getMinHeightBasedOnChildren( - parentCanvasWidget.widgetId, - changesSoFar, - true, - dynamicHeightLayoutTree, + minHeightInRows = Math.max( + minHeightInRows, + minCanvasHeightInRows, ); - // Add extra rows, this is to accommodate for padding and margins in the parent - minPossibleHeight = - minPossibleHeight + GridDefaults.CANVAS_EXTENSION_OFFSET; - // For widgets like Tabs Widget, some of the height is occupied by the // tabs themselves, the child canvas as a result has less number of rows available // To accommodate for this, we need to increase the new height by the offset amount. @@ -304,11 +339,7 @@ export function* updateWidgetAutoHeightSaga() { parentContainerLikeWidget.type, parentContainerLikeWidget, ); - minPossibleHeight += canvasHeightOffset; - minHeightInRows = Math.max(minPossibleHeight, minHeightInRows); - - // Setting this in a variable, as this will be the total scroll height in the canvas. - const maxBottomRow = minHeightInRows + 0; + minHeightInRows += canvasHeightOffset; // Make sure we're not overflowing the max height bounds const maxDynamicHeight = getWidgetMaxAutoHeight( @@ -317,25 +348,6 @@ export function* updateWidgetAutoHeightSaga() { minHeightInRows = Math.min(maxDynamicHeight, minHeightInRows); - // We need to make sure that the canvas widget doesn't have - // any extra scroll, to this end, we need to add the `minHeight` update - // for the canvas widgets. Canvas Widgets are never updated in other flows - // As they simply take up whatever space the parent has, but this doesn't effect - // the `minHeight`, which leads to scroll if the `minHeight` is a larger value. - // Also, for canvas widgets, the values are in pure pixels instead of rows. - widgetsToUpdate[parentCanvasWidgetId] = [ - { - propertyPath: "bottomRow", - propertyValue: - maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT, - }, - { - propertyPath: "minHeight", - propertyValue: - maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT, - }, - ]; - let layoutData = dynamicHeightLayoutTree[parentContainerLikeWidget.widgetId]; @@ -430,20 +442,21 @@ export function* updateWidgetAutoHeightSaga() { } } // Let's consider the minimum Canvas Height - let maxCanvasHeight = CANVAS_DEFAULT_MIN_HEIGHT_PX; + let maxCanvasHeightInRows = + CANVAS_DEFAULT_MIN_HEIGHT_PX / GridDefaults.DEFAULT_GRID_ROW_HEIGHT; // The same logic to compute the minimum height of the MainContainer // Based on how many rows are being occuped by children. - const maxPossibleCanvasHeight: number = yield getMinHeightBasedOnChildren( + const maxPossibleCanvasHeightInRows: number = yield getMinHeightBasedOnChildren( MAIN_CONTAINER_WIDGET_ID, changesSoFar, - false, + true, dynamicHeightLayoutTree, ); - maxCanvasHeight = Math.max( - maxPossibleCanvasHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT, - maxCanvasHeight, + maxCanvasHeightInRows = Math.max( + maxPossibleCanvasHeightInRows, + maxCanvasHeightInRows, ); // Add the MainContainer's update. @@ -451,9 +464,8 @@ export function* updateWidgetAutoHeightSaga() { { propertyPath: "bottomRow", propertyValue: - maxCanvasHeight + - GridDefaults.CANVAS_EXTENSION_OFFSET * - GridDefaults.DEFAULT_GRID_ROW_HEIGHT, + (maxCanvasHeightInRows + GridDefaults.MAIN_CANVAS_EXTENSION_OFFSET) * + GridDefaults.DEFAULT_GRID_ROW_HEIGHT, }, ]; diff --git a/app/client/src/selectors/propertyPaneSelectors.tsx b/app/client/src/selectors/propertyPaneSelectors.tsx index 35c9bf41c8..30c3761b7d 100644 --- a/app/client/src/selectors/propertyPaneSelectors.tsx +++ b/app/client/src/selectors/propertyPaneSelectors.tsx @@ -18,6 +18,7 @@ import { generateClassName } from "utils/generators"; import { getWidgets } from "sagas/selectors"; import { getCurrentPageId } from "selectors/editorSelectors"; import { generatePropertyKey } from "utils/editorContextUtils"; +import { RegisteredWidgetFeatures } from "utils/WidgetFeatures"; export type WidgetProperties = WidgetProps & { [EVALUATION_PATH]?: DataTreeEntity; @@ -63,6 +64,7 @@ export const getWidgetPropsForPropertyPane = createSelector( ); type WidgetPropertiesForPropertyPaneView = { + disabledWidgetFeatures?: RegisteredWidgetFeatures[]; type: string; widgetId: string; widgetName: string; @@ -77,6 +79,7 @@ export const getWidgetPropsForPropertyPaneView = createSelector( "widgetId", "widgetName", "displayName", + "disabledWidgetFeatures", ]) as WidgetPropertiesForPropertyPaneView, ); diff --git a/app/client/src/utils/WidgetFactory.tsx b/app/client/src/utils/WidgetFactory.tsx index db1429713e..61c764d58e 100644 --- a/app/client/src/utils/WidgetFactory.tsx +++ b/app/client/src/utils/WidgetFactory.tsx @@ -113,6 +113,7 @@ class WidgetFactory { propertyPaneContentConfig, features, PropertyPaneConfigTypes.CONTENT, + widgetType, ); const serializablePropertyPaneConfig = convertFunctionsToString( diff --git a/app/client/src/utils/WidgetFactoryHelpers.ts b/app/client/src/utils/WidgetFactoryHelpers.ts index 10700b3874..ed0b036b27 100644 --- a/app/client/src/utils/WidgetFactoryHelpers.ts +++ b/app/client/src/utils/WidgetFactoryHelpers.ts @@ -1,9 +1,12 @@ import { PropertyPaneConfig, PropertyPaneControlConfig, + PropertyPaneSectionConfig, } from "constants/PropertyControlConstants"; import { ValidationTypes } from "constants/WidgetValidation"; +import log from "loglevel"; import { generateReactKey } from "./generators"; +import { WidgetType } from "./WidgetFactory"; import { PropertyPaneConfigTemplates, RegisteredWidgetFeatures, @@ -74,6 +77,7 @@ export function enhancePropertyPaneConfig( config: PropertyPaneConfig[], features?: WidgetFeatures, configType?: PropertyPaneConfigTypes, + widgetType?: WidgetType, ) { // Enhance property pane with widget features // TODO(abhinav): The following "configType" check should come @@ -83,20 +87,28 @@ export function enhancePropertyPaneConfig( (configType === undefined || configType === PropertyPaneConfigTypes.CONTENT) ) { Object.keys(features).forEach((registeredFeature: string) => { + const { sectionIndex } = features[ + registeredFeature as RegisteredWidgetFeatures + ]; + const sectionName = (config[sectionIndex] as PropertyPaneSectionConfig) + ?.sectionName; + if (!sectionName || sectionName !== "General") { + log.error(`Invalid section index for feature: ${registeredFeature}`); + } if ( - Array.isArray(config[0].children) && + Array.isArray(config[sectionIndex].children) && PropertyPaneConfigTemplates[ registeredFeature as RegisteredWidgetFeatures ] ) { - config[0].children.push( + config[sectionIndex].children?.push( ...PropertyPaneConfigTemplates[ registeredFeature as RegisteredWidgetFeatures ], ); config = WidgetFeaturePropertyPaneEnhancements[ registeredFeature as RegisteredWidgetFeatures - ](config); + ](config, widgetType); } }); } diff --git a/app/client/src/utils/WidgetFeatures.ts b/app/client/src/utils/WidgetFeatures.ts index 5df40cf4bd..be0a768511 100644 --- a/app/client/src/utils/WidgetFeatures.ts +++ b/app/client/src/utils/WidgetFeatures.ts @@ -2,16 +2,32 @@ import { ReduxActionTypes } from "ce/constants/ReduxActionConstants"; import { PropertyPaneConfig, PropertyPaneControlConfig, + PropertyPaneSectionConfig, } from "constants/PropertyControlConstants"; -import { WidgetHeightLimits } from "constants/WidgetConstants"; +import { + GridDefaults, + WidgetHeightLimits, + WidgetType, +} from "constants/WidgetConstants"; +import { klona } from "klona/lite"; import { WidgetProps } from "widgets/BaseWidget"; import { WidgetConfiguration } from "widgets/constants"; +import WidgetFactory from "./WidgetFactory"; export enum RegisteredWidgetFeatures { DYNAMIC_HEIGHT = "dynamicHeight", } -export type WidgetFeatures = Record; +interface WidgetFeatureConfig { + active: boolean; + defaultValue?: DynamicHeight; + sectionIndex: number; +} + +export type WidgetFeatures = Record< + RegisteredWidgetFeatures, + WidgetFeatureConfig +>; export enum DynamicHeight { AUTO_HEIGHT = "AUTO_HEIGHT", @@ -19,7 +35,7 @@ export enum DynamicHeight { AUTO_HEIGHT_WITH_LIMITS = "AUTO_HEIGHT_WITH_LIMITS", } -/* This contains all properties which will be added +/* This contains all properties which will be added to a widget, automatically, by the Appsmith platform Each feature, is a unique key, whose value is an object with the list of properties to be added to a widget along @@ -44,11 +60,14 @@ export const WidgetFeaturePropertyEnhancements: Record< > = { [RegisteredWidgetFeatures.DYNAMIC_HEIGHT]: (config: WidgetConfiguration) => { const newProperties: Partial = {}; + newProperties.dynamicHeight = + config.features?.dynamicHeight?.defaultValue || DynamicHeight.AUTO_HEIGHT; if (config.isCanvas) { newProperties.dynamicHeight = DynamicHeight.AUTO_HEIGHT; + newProperties.minDynamicHeight = + config.defaults.minDynamicHeight || + WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS; newProperties.shouldScrollContents = true; - newProperties.originalTopRow = config.defaults.topRow; - newProperties.originalBottomRow = config.defaults.bottomRow; } if (config.defaults.overflow) newProperties.overflow = "NONE"; return newProperties; @@ -91,16 +110,22 @@ function findAndUpdatePropertyPaneControlConfig( export const WidgetFeaturePropertyPaneEnhancements: Record< RegisteredWidgetFeatures, - (config: PropertyPaneConfig[]) => PropertyPaneConfig[] + ( + config: PropertyPaneConfig[], + widgetType?: WidgetType, + ) => PropertyPaneConfig[] > = { - [RegisteredWidgetFeatures.DYNAMIC_HEIGHT]: (config: PropertyPaneConfig[]) => { + [RegisteredWidgetFeatures.DYNAMIC_HEIGHT]: ( + config: PropertyPaneConfig[], + widgetType?: WidgetType, + ) => { function hideWhenDynamicHeightIsEnabled(props: WidgetProps) { return ( props.dynamicHeight === DynamicHeight.AUTO_HEIGHT_WITH_LIMITS || props.dynamicHeight === DynamicHeight.AUTO_HEIGHT ); } - return findAndUpdatePropertyPaneControlConfig(config, { + let update = findAndUpdatePropertyPaneControlConfig(config, { shouldScrollContents: { hidden: hideWhenDynamicHeightIsEnabled, dependencies: ["dynamicHeight"], @@ -118,6 +143,23 @@ export const WidgetFeaturePropertyPaneEnhancements: Record< dependencies: ["dynamicHeight"], }, }); + if (widgetType === "MODAL_WIDGET") { + update = findAndUpdatePropertyPaneControlConfig(update, { + dynamicHeight: { + options: [ + { + label: "Auto Height", + value: DynamicHeight.AUTO_HEIGHT, + }, + { + label: "Fixed", + value: DynamicHeight.FIXED, + }, + ], + }, + }); + } + return update; }, }; @@ -163,7 +205,8 @@ function updateMinMaxDynamicHeight( ) { updates.push({ propertyPath: "maxDynamicHeight", - propertyValue: props.bottomRow - props.topRow, + propertyValue: + props.bottomRow - props.topRow + GridDefaults.CANVAS_EXTENSION_OFFSET, }); } @@ -175,10 +218,13 @@ function updateMinMaxDynamicHeight( }); } } else if (propertyValue === DynamicHeight.AUTO_HEIGHT) { + const minHeightInRows = props.isCanvas + ? WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS + : WidgetHeightLimits.MIN_HEIGHT_IN_ROWS; updates.push( { propertyPath: "minDynamicHeight", - propertyValue: WidgetHeightLimits.MIN_HEIGHT_IN_ROWS, + propertyValue: minHeightInRows, }, { propertyPath: "maxDynamicHeight", @@ -245,7 +291,7 @@ function updateMinMaxDynamicHeight( // TODO FEATURE:(abhinav) Add validations to these properties const CONTAINER_SCROLL_HELPER_TEXT = - "While editing, this widget may scroll contents to facilitate adding widgets. When published, the widget may not scroll contents."; + "This widget shows an internal scroll when you add widgets in edit mode. It'll resize after you've added widgets. The scroll won't exist in view mode."; export const PropertyPaneConfigTemplates: Record< RegisteredWidgetFeatures, @@ -295,3 +341,36 @@ export const PropertyPaneConfigTemplates: Record< }, ], }; + +//TODO make this logic a lot cleaner +export function disableWidgetFeatures( + widgetType: WidgetType, + disabledWidgetFeatures?: string[], +): PropertyPaneConfig[] { + const widgetConfig = WidgetFactory.getWidgetPropertyPaneContentConfig( + widgetType, + ) as PropertyPaneConfig[]; + + if (!disabledWidgetFeatures || disabledWidgetFeatures.length <= 0) + return widgetConfig; + + const clonedConfig = klona(widgetConfig); + const GeneralConfig = clonedConfig.find( + (sectionConfig) => + (sectionConfig as PropertyPaneSectionConfig)?.sectionName === "General", + ); + + for (let i = 0; i < (GeneralConfig?.children?.length || -1); i++) { + const config = GeneralConfig?.children?.[i]; + if ( + disabledWidgetFeatures.indexOf( + (config as PropertyPaneControlConfig)?.propertyName || "", + ) > -1 + ) { + GeneralConfig?.children?.splice(i, 1); + i--; + } + } + + return clonedConfig; +} diff --git a/app/client/src/utils/autoHeight/generateTree.ts b/app/client/src/utils/autoHeight/generateTree.ts index e18eabf5c3..9c03a91de6 100644 --- a/app/client/src/utils/autoHeight/generateTree.ts +++ b/app/client/src/utils/autoHeight/generateTree.ts @@ -11,7 +11,15 @@ export function generateTree( previousTree: Record, ): Record { // If widget doesn't exist in this DS, this means that its height changes does not effect any other sibling - spaces.sort((a, b) => a.top - b.top); // Sort based on position, top to bottom, so that we know which is above the other + spaces.sort((a, b) => { + //if both are of the same level and previous tree exists, check originalTops + if (a.top === b.top && previousTree[a.id] && previousTree[b.id]) { + return ( + previousTree[a.id].originalTopRow - previousTree[b.id].originalTopRow + ); + } + return a.top - b.top; + }); // Sort based on position, top to bottom, so that we know which is above the other const _spaces = [...spaces]; const aboveMap: Record = {}; diff --git a/app/client/src/widgets/CheckboxGroupWidget/component/index.tsx b/app/client/src/widgets/CheckboxGroupWidget/component/index.tsx index 38869e60ad..43979bdf54 100644 --- a/app/client/src/widgets/CheckboxGroupWidget/component/index.tsx +++ b/app/client/src/widgets/CheckboxGroupWidget/component/index.tsx @@ -46,10 +46,9 @@ const InputContainer = styled.div` ? `flex-start` : `center`}; width: 100%; - height: ${({ inline, isDynamicHeightEnabled }) => - inline && !isDynamicHeightEnabled ? "32px" : "100%"}; flex-grow: 1; height: 100%; + border: 1px solid transparent; .${Classes.CONTROL} { @@ -72,6 +71,7 @@ export interface CheckboxGroupContainerProps { export const CheckboxGroupContainer = styled.div` ${labelLayoutStyles} & .${LABEL_CONTAINER_CLASS} { + align-self: center; ${({ labelPosition }) => labelPosition === LabelPosition.Left && "min-height: 30px"}; } @@ -149,6 +149,7 @@ export interface CheckboxGroupComponentProps extends ComponentProps { labelTextSize?: TextSize; labelStyle?: string; labelWidth?: number; + labelTooltip?: string; accentColor: string; borderRadius: string; } @@ -168,6 +169,7 @@ function CheckboxGroupComponent(props: CheckboxGroupComponentProps) { labelText, labelTextColor, labelTextSize, + labelTooltip, labelWidth, onChange, onSelectAllChange, @@ -205,6 +207,7 @@ function CheckboxGroupComponent(props: CheckboxGroupComponentProps) { disabled={isDisabled} fontSize={labelTextSize} fontStyle={labelStyle} + helpText={labelTooltip} inline={isInline} isDynamicHeightEnabled={isDynamicHeightEnabled} optionCount={optionCount} diff --git a/app/client/src/widgets/CheckboxGroupWidget/index.ts b/app/client/src/widgets/CheckboxGroupWidget/index.ts index 3bf6f9e226..d623e4fe93 100644 --- a/app/client/src/widgets/CheckboxGroupWidget/index.ts +++ b/app/client/src/widgets/CheckboxGroupWidget/index.ts @@ -5,7 +5,10 @@ import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + active: true, + }, }, type: Widget.getWidgetType(), name: "Checkbox Group", diff --git a/app/client/src/widgets/CheckboxGroupWidget/widget/index.tsx b/app/client/src/widgets/CheckboxGroupWidget/widget/index.tsx index 60cba9abba..9d352b40a3 100644 --- a/app/client/src/widgets/CheckboxGroupWidget/widget/index.tsx +++ b/app/client/src/widgets/CheckboxGroupWidget/widget/index.tsx @@ -1,26 +1,23 @@ import React from "react"; import { compact, xor } from "lodash"; - -import { - ValidationResponse, - ValidationTypes, -} from "constants/WidgetValidation"; import { TextSize, WidgetType } from "constants/WidgetConstants"; import { DerivedPropertiesMap } from "utils/WidgetFactory"; import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget"; import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; import { AutocompleteDataType } from "utils/autocomplete/TernServer"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; - +import { Alignment } from "@blueprintjs/core"; +import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants"; +import CheckboxGroupComponent from "../component"; +import { OptionProps, SelectAllState, SelectAllStates } from "../constants"; +import { + ValidationResponse, + ValidationTypes, +} from "constants/WidgetValidation"; import { CheckboxGroupAlignmentTypes, LabelPosition, } from "components/constants"; -import { Alignment } from "@blueprintjs/core"; -import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants"; - -import CheckboxGroupComponent from "../component"; -import { OptionProps, SelectAllState, SelectAllStates } from "../constants"; import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils"; export function defaultSelectedValuesValidation( @@ -217,6 +214,16 @@ class CheckboxGroupWidget extends BaseWidget< { sectionName: "General", children: [ + { + helpText: "Show help text or details about current input", + propertyName: "labelTooltip", + label: "Tooltip", + controlType: "INPUT_TEXT", + placeholderText: "Value must be atleast 6 chars", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, { propertyName: "isVisible", label: "Visible", @@ -561,6 +568,7 @@ class CheckboxGroupWidget extends BaseWidget< labelText={this.props.labelText} labelTextColor={this.props.labelTextColor} labelTextSize={this.props.labelTextSize} + labelTooltip={this.props.labelTooltip} labelWidth={this.getLabelWidth()} onChange={this.handleCheckboxChange} onSelectAllChange={this.handleSelectAllChange} diff --git a/app/client/src/widgets/CheckboxWidget/index.ts b/app/client/src/widgets/CheckboxWidget/index.ts index 62a94665b4..8108fe5147 100644 --- a/app/client/src/widgets/CheckboxWidget/index.ts +++ b/app/client/src/widgets/CheckboxWidget/index.ts @@ -5,7 +5,10 @@ import { AlignWidgetTypes } from "widgets/constants"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 2, + active: true, + }, }, type: Widget.getWidgetType(), name: "Checkbox", diff --git a/app/client/src/widgets/ContainerWidget/index.ts b/app/client/src/widgets/ContainerWidget/index.ts index 3ce6401aa8..9cd1877060 100644 --- a/app/client/src/widgets/ContainerWidget/index.ts +++ b/app/client/src/widgets/ContainerWidget/index.ts @@ -1,5 +1,6 @@ import { ButtonBoxShadowTypes } from "components/constants"; import { Colors } from "constants/Colors"; +import { WidgetHeightLimits } from "constants/WidgetConstants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; @@ -9,12 +10,15 @@ export const CONFIG = { iconSVG: IconSVG, isCanvas: true, features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 0, + active: true, + }, }, searchTags: ["div", "parent", "group"], defaults: { backgroundColor: "#FFFFFF", - rows: 40, + rows: WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS, columns: 24, widgetName: "Container", containerStyle: "card", diff --git a/app/client/src/widgets/CurrencyInputWidget/index.ts b/app/client/src/widgets/CurrencyInputWidget/index.ts index 71cb716ae7..df2f46b236 100644 --- a/app/client/src/widgets/CurrencyInputWidget/index.ts +++ b/app/client/src/widgets/CurrencyInputWidget/index.ts @@ -3,10 +3,15 @@ import IconSVG from "./icon.svg"; import { CONFIG as BaseConfig } from "widgets/BaseInputWidget"; import { getDefaultCurrency } from "./component/CurrencyCodeDropdown"; import { LabelPosition } from "components/constants"; +import { DynamicHeight } from "utils/WidgetFeatures"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "Currency Input", diff --git a/app/client/src/widgets/DatePickerWidget2/index.ts b/app/client/src/widgets/DatePickerWidget2/index.ts index 45db65f010..deb419caf5 100644 --- a/app/client/src/widgets/DatePickerWidget2/index.ts +++ b/app/client/src/widgets/DatePickerWidget2/index.ts @@ -1,13 +1,18 @@ import { Alignment } from "@blueprintjs/core"; import { LabelPosition } from "components/constants"; import moment from "moment"; +import { DynamicHeight } from "utils/WidgetFeatures"; import { TimePrecision } from "./constants"; import IconSVG from "./icon.svg"; import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "DatePicker", diff --git a/app/client/src/widgets/FormWidget/index.ts b/app/client/src/widgets/FormWidget/index.ts index 440e22c498..14da8291fe 100644 --- a/app/client/src/widgets/FormWidget/index.ts +++ b/app/client/src/widgets/FormWidget/index.ts @@ -10,7 +10,10 @@ export const CONFIG = { needsMeta: true, isCanvas: true, features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 0, + active: true, + }, }, searchTags: ["group"], defaults: { diff --git a/app/client/src/widgets/InputWidgetV2/index.ts b/app/client/src/widgets/InputWidgetV2/index.ts index 3c94d70c9f..53f977abff 100644 --- a/app/client/src/widgets/InputWidgetV2/index.ts +++ b/app/client/src/widgets/InputWidgetV2/index.ts @@ -2,10 +2,15 @@ import Widget from "./widget"; import IconSVG from "./icon.svg"; import { CONFIG as BaseConfig } from "widgets/BaseInputWidget"; import { LabelPosition } from "components/constants"; +import { DynamicHeight } from "utils/WidgetFeatures"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "Input", diff --git a/app/client/src/widgets/JSONFormWidget/component/Form.tsx b/app/client/src/widgets/JSONFormWidget/component/Form.tsx index 90884a5a7e..65beda4101 100644 --- a/app/client/src/widgets/JSONFormWidget/component/Form.tsx +++ b/app/client/src/widgets/JSONFormWidget/component/Form.tsx @@ -156,6 +156,7 @@ function Form( >({ activeClassName: FOOTER_SCROLL_ACTIVE_CLASS_NAME, fixedFooter, + ref: ref as React.MutableRefObject, }); const onReset = ( @@ -262,12 +263,11 @@ function Form( } scrollContents={scrollContents} > {title} diff --git a/app/client/src/widgets/JSONFormWidget/component/useFixedFooter.ts b/app/client/src/widgets/JSONFormWidget/component/useFixedFooter.ts index 9055bb02f6..6fe9ed3350 100644 --- a/app/client/src/widgets/JSONFormWidget/component/useFixedFooter.ts +++ b/app/client/src/widgets/JSONFormWidget/component/useFixedFooter.ts @@ -4,6 +4,7 @@ import { useLayoutEffect, useRef } from "react"; type UseFixedFooterProps = { fixedFooter: boolean; activeClassName: string; + ref: React.MutableRefObject; }; const ERROR_MARGIN = 2; @@ -21,10 +22,10 @@ const hasOverflowingContent = (element: HTMLElement) => { const THROTTLE_TIMEOUT = 50; function useFixedFooter< - TBodyElement extends HTMLElement = HTMLDivElement, + HTMLDivElement extends HTMLElement, TFooterElement extends HTMLElement = HTMLDivElement ->({ activeClassName, fixedFooter }: UseFixedFooterProps) { - const bodyRef = useRef(null); +>({ activeClassName, fixedFooter, ref }: UseFixedFooterProps) { + const bodyRef = ref; const footerRef = useRef(null); const isOverflowing = bodyRef.current diff --git a/app/client/src/widgets/JSONFormWidget/index.ts b/app/client/src/widgets/JSONFormWidget/index.ts index fb301ef0bb..34b3b9f3bd 100644 --- a/app/client/src/widgets/JSONFormWidget/index.ts +++ b/app/client/src/widgets/JSONFormWidget/index.ts @@ -3,6 +3,7 @@ import { Colors } from "constants/Colors"; import Widget, { JSONFormWidgetProps } from "./widget"; import { ButtonVariantTypes } from "components/constants"; import { BlueprintOperationTypes } from "widgets/constants"; +import { DynamicHeight } from "utils/WidgetFeatures"; const SUBMIT_BUTTON_DEFAULT_STYLES = { buttonVariant: ButtonVariantTypes.PRIMARY, @@ -14,7 +15,11 @@ const RESET_BUTTON_DEFAULT_STYLES = { export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 1, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "JSON Form", diff --git a/app/client/src/widgets/JSONFormWidget/widget/index.tsx b/app/client/src/widgets/JSONFormWidget/widget/index.tsx index 5f366b35cd..3bf62e1e56 100644 --- a/app/client/src/widgets/JSONFormWidget/widget/index.tsx +++ b/app/client/src/widgets/JSONFormWidget/widget/index.tsx @@ -29,13 +29,6 @@ import { import { ButtonStyleProps } from "widgets/ButtonWidget/component"; import { BoxShadow } from "components/designSystems/appsmith/WidgetStyleContainer"; import { convertSchemaItemToFormData } from "../helper"; -import { GridDefaults } from "constants/WidgetConstants"; -import { - getWidgetMaxAutoHeight, - getWidgetMinAutoHeight, - isAutoHeightEnabledForWidget, -} from "widgets/WidgetUtils"; - export interface JSONFormWidgetProps extends WidgetProps { autoGenerateForm?: boolean; borderColor?: string; @@ -151,43 +144,6 @@ class JSONFormWidget extends BaseWidget< this.state.metaInternalFieldState, schema, ); - let height = this.formRef?.current?.scrollHeight || 0; - - if (isAutoHeightEnabledForWidget(this.props)) { - const maxDynamicHeight = getWidgetMaxAutoHeight(this.props); - const minDynamicHeight = getWidgetMinAutoHeight(this.props); - const footerHeight = 80; // TODO(abhinav): Get it from the component. Check with Ashit - - if ( - maxDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT < - height + footerHeight - ) { - height = - maxDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT - - footerHeight; - } else if ( - minDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT > - height + footerHeight - ) { - height = - minDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT - - footerHeight; - } - const totalHeight = footerHeight + height; - const { componentHeight } = this.getComponentDimensions(); - - const expectedHeightInPixels = - Math.ceil(totalHeight / GridDefaults.DEFAULT_GRID_ROW_HEIGHT) * - GridDefaults.DEFAULT_GRID_ROW_HEIGHT; - - if ( - height && - Math.abs(componentHeight - expectedHeightInPixels) > - GridDefaults.DEFAULT_GRID_ROW_HEIGHT - ) { - this.updateAutoHeight(expectedHeightInPixels); - } - } } computeDynamicPropertyPathList = (schema: Schema) => { diff --git a/app/client/src/widgets/ListWidget/index.ts b/app/client/src/widgets/ListWidget/index.ts index ce584ce285..4c57278408 100644 --- a/app/client/src/widgets/ListWidget/index.ts +++ b/app/client/src/widgets/ListWidget/index.ts @@ -3,6 +3,7 @@ import { combineDynamicBindings, getDynamicBindings, } from "utils/DynamicBindingUtils"; +import { RegisteredWidgetFeatures } from "utils/WidgetFeatures"; import { WidgetProps } from "widgets/BaseWidget"; import { BlueprintOperationTypes, @@ -122,6 +123,9 @@ export const CONFIG = { isDeletable: false, disallowCopy: true, disablePropertyPane: true, + disabledWidgetFeatures: [ + RegisteredWidgetFeatures.DYNAMIC_HEIGHT, + ], openParentPropertyPane: true, children: [], blueprint: { diff --git a/app/client/src/widgets/ModalWidget/index.ts b/app/client/src/widgets/ModalWidget/index.ts index 78a9401cc6..5399322f6b 100644 --- a/app/client/src/widgets/ModalWidget/index.ts +++ b/app/client/src/widgets/ModalWidget/index.ts @@ -21,7 +21,10 @@ export const CONFIG = { needsMeta: true, isCanvas: true, features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 0, + active: true, + }, }, searchTags: ["dialog", "popup", "notification"], defaults: { @@ -29,6 +32,7 @@ export const CONFIG = { columns: 24, width: 456, height: GridDefaults.DEFAULT_GRID_ROW_HEIGHT * 24, + minDynamicHeight: 24, canEscapeKeyClose: true, animateLoading: true, // detachFromLayout is set true for widgets that are not bound to the widgets within the layout. diff --git a/app/client/src/widgets/MultiSelectTreeWidget/index.ts b/app/client/src/widgets/MultiSelectTreeWidget/index.ts index b9c3251e8f..0b078f0589 100644 --- a/app/client/src/widgets/MultiSelectTreeWidget/index.ts +++ b/app/client/src/widgets/MultiSelectTreeWidget/index.ts @@ -1,11 +1,16 @@ import { Alignment } from "@blueprintjs/core"; import { LabelPosition } from "components/constants"; +import { DynamicHeight } from "utils/WidgetFeatures"; import IconSVG from "./icon.svg"; import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "Multi TreeSelect", diff --git a/app/client/src/widgets/MultiSelectWidgetV2/index.ts b/app/client/src/widgets/MultiSelectWidgetV2/index.ts index 86d5738f13..bfd41ad5ad 100644 --- a/app/client/src/widgets/MultiSelectWidgetV2/index.ts +++ b/app/client/src/widgets/MultiSelectWidgetV2/index.ts @@ -2,10 +2,15 @@ import Widget from "./widget"; import IconSVG from "./icon.svg"; import { LabelPosition } from "components/constants"; import { Alignment } from "@blueprintjs/core"; +import { DynamicHeight } from "utils/WidgetFeatures"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 4, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "MultiSelect", diff --git a/app/client/src/widgets/PhoneInputWidget/index.ts b/app/client/src/widgets/PhoneInputWidget/index.ts index a227d42ebd..61e469a4da 100644 --- a/app/client/src/widgets/PhoneInputWidget/index.ts +++ b/app/client/src/widgets/PhoneInputWidget/index.ts @@ -3,10 +3,15 @@ import IconSVG from "./icon.svg"; import { CONFIG as BaseConfig } from "widgets/BaseInputWidget"; import { getDefaultISDCode } from "./component/ISDCodeDropdown"; import { LabelPosition } from "components/constants"; +import { DynamicHeight } from "utils/WidgetFeatures"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "Phone Input", diff --git a/app/client/src/widgets/RadioGroupWidget/component/index.tsx b/app/client/src/widgets/RadioGroupWidget/component/index.tsx index 1ff0740899..7ffe291311 100644 --- a/app/client/src/widgets/RadioGroupWidget/component/index.tsx +++ b/app/client/src/widgets/RadioGroupWidget/component/index.tsx @@ -1,11 +1,11 @@ import React, { useCallback } from "react"; import styled from "styled-components"; import { ComponentProps } from "widgets/BaseComponent"; -import { RadioOption } from "../constants"; import { RadioGroup, Radio, Alignment, Classes } from "@blueprintjs/core"; import { TextSize } from "constants/WidgetConstants"; import { BlueprintRadioSwitchGroupTransform } from "constants/DefaultTheme"; import { LabelPosition } from "components/constants"; +import { RadioOption } from "../constants"; import LabelWithTooltip, { labelLayoutStyles, LABEL_CONTAINER_CLASS, @@ -18,7 +18,9 @@ export interface RadioGroupContainerProps { export const RadioGroupContainer = styled.div` ${labelLayoutStyles} + & .${LABEL_CONTAINER_CLASS} { + align-self: center; ${({ labelPosition }) => labelPosition === LabelPosition.Left && "min-height: 30px"}; } @@ -37,8 +39,6 @@ export interface StyledRadioGroupProps { const StyledRadioGroup = styled(RadioGroup)` ${BlueprintRadioSwitchGroupTransform} - height: ${({ inline, isDynamicHeightEnabled }) => - inline && !isDynamicHeightEnabled ? "32px" : "100%"}; .${Classes.CONTROL} { & input:checked ~ .${Classes.CONTROL_INDICATOR} { @@ -48,8 +48,12 @@ const StyledRadioGroup = styled(RadioGroup)` & input:disabled:checked ~ .${Classes.CONTROL_INDICATOR} { &:before { - opacity: 1; - background-image: radial-gradient(var( --wds-color-bg-disabled-strong), var( --wds-color-bg-disabled-strong) 28%, transparent 32%) + opacity: 1; + background-image: radial-gradient( + var(--wds-color-bg-disabled-strong), + var(--wds-color-bg-disabled-strong) 28%, + transparent 32% + ); } } } @@ -76,6 +80,7 @@ function RadioGroupComponent(props: RadioGroupComponentProps) { labelText, labelTextColor, labelTextSize, + labelTooltip, labelWidth, loading, onRadioSelectionChange, @@ -108,6 +113,7 @@ function RadioGroupComponent(props: RadioGroupComponentProps) { disabled={disabled} fontSize={labelTextSize} fontStyle={labelStyle} + helpText={labelTooltip} inline={inline} isDynamicHeightEnabled={isDynamicHeightEnabled} loading={loading} @@ -165,6 +171,7 @@ export interface RadioGroupComponentProps extends ComponentProps { labelTextSize?: TextSize; labelStyle?: string; labelWidth?: number; + labelTooltip?: string; widgetId: string; height?: number; accentColor: string; diff --git a/app/client/src/widgets/RadioGroupWidget/index.ts b/app/client/src/widgets/RadioGroupWidget/index.ts index c9522d7cbd..a16b817806 100644 --- a/app/client/src/widgets/RadioGroupWidget/index.ts +++ b/app/client/src/widgets/RadioGroupWidget/index.ts @@ -9,7 +9,10 @@ export const CONFIG = { iconSVG: IconSVG, needsMeta: true, features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + active: true, + }, }, searchTags: ["choice"], defaults: { diff --git a/app/client/src/widgets/RadioGroupWidget/widget/index.tsx b/app/client/src/widgets/RadioGroupWidget/widget/index.tsx index 8acd2c8845..73ff9af7cc 100644 --- a/app/client/src/widgets/RadioGroupWidget/widget/index.tsx +++ b/app/client/src/widgets/RadioGroupWidget/widget/index.tsx @@ -1,20 +1,19 @@ import React from "react"; import { Alignment } from "@blueprintjs/core"; import { isArray, compact, isNumber } from "lodash"; - import BaseWidget, { WidgetProps, WidgetState } from "../../BaseWidget"; import { TextSize, WidgetType } from "constants/WidgetConstants"; import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants"; import { AutocompleteDataType } from "utils/autocomplete/TernServer"; import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; -import { - ValidationResponse, - ValidationTypes, -} from "constants/WidgetValidation"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; import { RadioOption } from "../constants"; import { LabelPosition } from "components/constants"; import RadioGroupComponent from "../component"; +import { + ValidationResponse, + ValidationTypes, +} from "constants/WidgetValidation"; import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils"; /** @@ -293,6 +292,16 @@ class RadioGroupWidget extends BaseWidget { { sectionName: "General", children: [ + { + helpText: "Show help text or details about current input", + propertyName: "labelTooltip", + label: "Tooltip", + controlType: "INPUT_TEXT", + placeholderText: "Value must be atleast 6 chars", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, { helpText: "Controls the visibility of the widget", propertyName: "isVisible", @@ -545,6 +554,7 @@ class RadioGroupWidget extends BaseWidget { labelText={label} labelTextColor={labelTextColor} labelTextSize={labelTextSize} + labelTooltip={this.props.labelTooltip} labelWidth={this.getLabelWidth()} loading={isLoading} onRadioSelectionChange={this.onRadioSelectionChange} diff --git a/app/client/src/widgets/RateWidget/index.ts b/app/client/src/widgets/RateWidget/index.ts index 61c561f04e..007652ee73 100644 --- a/app/client/src/widgets/RateWidget/index.ts +++ b/app/client/src/widgets/RateWidget/index.ts @@ -4,7 +4,10 @@ import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 1, + active: true, + }, }, type: Widget.getWidgetType(), name: "Rating", diff --git a/app/client/src/widgets/RichTextEditorWidget/index.ts b/app/client/src/widgets/RichTextEditorWidget/index.ts index 06938dcfc0..0a591b2dd7 100644 --- a/app/client/src/widgets/RichTextEditorWidget/index.ts +++ b/app/client/src/widgets/RichTextEditorWidget/index.ts @@ -1,5 +1,6 @@ import { Alignment } from "@blueprintjs/core"; import { LabelPosition } from "components/constants"; +import { DynamicHeight } from "utils/WidgetFeatures"; import IconSVG from "./icon.svg"; import Widget from "./widget"; @@ -10,7 +11,11 @@ export const CONFIG = { needsMeta: true, searchTags: ["input", "rte"], features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, defaults: { defaultText: "This is the initial content of the editor", diff --git a/app/client/src/widgets/SelectWidget/index.ts b/app/client/src/widgets/SelectWidget/index.ts index 0b28c63fd0..c716dc664b 100644 --- a/app/client/src/widgets/SelectWidget/index.ts +++ b/app/client/src/widgets/SelectWidget/index.ts @@ -2,10 +2,15 @@ import Widget from "./widget"; import IconSVG from "./icon.svg"; import { LabelPosition } from "components/constants"; import { Alignment } from "@blueprintjs/core"; +import { DynamicHeight } from "utils/WidgetFeatures"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 4, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "Select", diff --git a/app/client/src/widgets/SingleSelectTreeWidget/index.ts b/app/client/src/widgets/SingleSelectTreeWidget/index.ts index ba2087d1d3..5c0baaf2f9 100644 --- a/app/client/src/widgets/SingleSelectTreeWidget/index.ts +++ b/app/client/src/widgets/SingleSelectTreeWidget/index.ts @@ -1,11 +1,16 @@ import { Alignment } from "@blueprintjs/core"; import { LabelPosition } from "components/constants"; +import { DynamicHeight } from "utils/WidgetFeatures"; import IconSVG from "./icon.svg"; import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + defaultValue: DynamicHeight.FIXED, + active: true, + }, }, type: Widget.getWidgetType(), name: "TreeSelect", diff --git a/app/client/src/widgets/StatboxWidget/index.ts b/app/client/src/widgets/StatboxWidget/index.ts index 151cb218be..23d4e9c22c 100644 --- a/app/client/src/widgets/StatboxWidget/index.ts +++ b/app/client/src/widgets/StatboxWidget/index.ts @@ -6,7 +6,10 @@ import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 0, + active: true, + }, }, type: Widget.getWidgetType(), name: "Stats Box", @@ -21,6 +24,7 @@ export const CONFIG = { backgroundColor: "white", borderWidth: "1", borderColor: Colors.GREY_5, + minDynamicHeight: 14, children: [], blueprint: { view: [ diff --git a/app/client/src/widgets/SwitchGroupWidget/component/index.tsx b/app/client/src/widgets/SwitchGroupWidget/component/index.tsx index d076f5456c..75bbb2e8a0 100644 --- a/app/client/src/widgets/SwitchGroupWidget/component/index.tsx +++ b/app/client/src/widgets/SwitchGroupWidget/component/index.tsx @@ -1,7 +1,6 @@ import React from "react"; import styled from "styled-components"; import { Alignment } from "@blueprintjs/core"; - import { BlueprintRadioSwitchGroupTransform } from "constants/DefaultTheme"; import { LabelPosition } from "components/constants"; import { TextSize } from "constants/WidgetConstants"; @@ -20,6 +19,7 @@ export interface SwitchGroupContainerProps { export const SwitchGroupContainer = styled.div` ${labelLayoutStyles} & .${LABEL_CONTAINER_CLASS} { + align-self: center; ${({ labelPosition }) => labelPosition === LabelPosition.Left && "min-height: 30px"}; } @@ -37,9 +37,8 @@ export interface InputContainerProps { } export const InputContainer = styled.div` - ${BlueprintRadioSwitchGroupTransform} - height: ${({ inline, isDynamicHeightEnabled }) => - inline && !isDynamicHeightEnabled ? "32px" : "100%"}; + ${BlueprintRadioSwitchGroupTransform}; + border: 1px solid transparent; ${({ theme, valid }) => !valid && @@ -68,6 +67,7 @@ function SwitchGroupComponent(props: SwitchGroupComponentProps) { labelText, labelTextColor, labelTextSize, + labelTooltip, labelWidth, onChange, options, @@ -92,6 +92,7 @@ function SwitchGroupComponent(props: SwitchGroupComponentProps) { disabled={disabled} fontSize={labelTextSize} fontStyle={labelStyle} + helpText={labelTooltip} inline={inline} isDynamicHeightEnabled={isDynamicHeightEnabled} optionCount={optionCount} @@ -147,6 +148,7 @@ export interface SwitchGroupComponentProps { labelTextSize?: TextSize; labelStyle?: string; labelWidth?: number; + labelTooltip?: string; widgetId: string; height: number; accentColor: string; diff --git a/app/client/src/widgets/SwitchGroupWidget/index.ts b/app/client/src/widgets/SwitchGroupWidget/index.ts index fda2dfc76e..2f94d53849 100644 --- a/app/client/src/widgets/SwitchGroupWidget/index.ts +++ b/app/client/src/widgets/SwitchGroupWidget/index.ts @@ -5,7 +5,10 @@ import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 3, + active: true, + }, }, type: Widget.getWidgetType(), name: "Switch Group", // The display name which will be made in uppercase and show in the widgets panel ( can have spaces ) diff --git a/app/client/src/widgets/SwitchGroupWidget/widget/index.tsx b/app/client/src/widgets/SwitchGroupWidget/widget/index.tsx index 8beab6c360..221ce00cbb 100644 --- a/app/client/src/widgets/SwitchGroupWidget/widget/index.tsx +++ b/app/client/src/widgets/SwitchGroupWidget/widget/index.tsx @@ -1,17 +1,15 @@ import React from "react"; import { Alignment } from "@blueprintjs/core"; import { isString, xor } from "lodash"; - import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget"; import { DerivedPropertiesMap } from "utils/WidgetFactory"; import { ValidationTypes } from "constants/WidgetValidation"; import { EventType } from "constants/AppsmithActionConstants/ActionConstants"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; - -import SwitchGroupComponent, { OptionProps } from "../component"; import { LabelPosition } from "components/constants"; import { TextSize } from "constants/WidgetConstants"; import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants"; +import SwitchGroupComponent, { OptionProps } from "../component"; import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils"; class SwitchGroupWidget extends BaseWidget< @@ -177,6 +175,16 @@ class SwitchGroupWidget extends BaseWidget< { sectionName: "General", children: [ + { + helpText: "Show help text or details about current input", + propertyName: "labelTooltip", + label: "Tooltip", + controlType: "INPUT_TEXT", + placeholderText: "Value must be atleast 6 chars", + isBindProperty: true, + isTriggerProperty: false, + validation: { type: ValidationTypes.TEXT }, + }, { propertyName: "isVisible", helpText: "Controls the visibility of the widget", @@ -421,6 +429,7 @@ class SwitchGroupWidget extends BaseWidget< labelText, labelTextColor, labelTextSize, + labelTooltip, options, selectedValues, topRow, @@ -453,6 +462,7 @@ class SwitchGroupWidget extends BaseWidget< labelText={labelText} labelTextColor={labelTextColor} labelTextSize={labelTextSize} + labelTooltip={labelTooltip} labelWidth={this.getLabelWidth()} onChange={this.handleSwitchStateChange} options={_options} diff --git a/app/client/src/widgets/SwitchWidget/component/index.tsx b/app/client/src/widgets/SwitchWidget/component/index.tsx index d404b6a541..0f2239ff33 100644 --- a/app/client/src/widgets/SwitchWidget/component/index.tsx +++ b/app/client/src/widgets/SwitchWidget/component/index.tsx @@ -63,10 +63,6 @@ export const StyledSwitch = styled(Switch)<{ $accentColor: string; inline?: boolean; }>` - &.${Classes.CONTROL} { - margin: 0; - } - &.${Classes.CONTROL} { & input:checked ~ .${Classes.CONTROL_INDICATOR} { background: ${({ $accentColor }) => `${$accentColor}`} !important; diff --git a/app/client/src/widgets/SwitchWidget/index.ts b/app/client/src/widgets/SwitchWidget/index.ts index 75f086bef5..bc21b95b3a 100644 --- a/app/client/src/widgets/SwitchWidget/index.ts +++ b/app/client/src/widgets/SwitchWidget/index.ts @@ -5,7 +5,10 @@ import { AlignWidgetTypes } from "widgets/constants"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 1, + active: true, + }, }, type: Widget.getWidgetType(), name: "Switch", diff --git a/app/client/src/widgets/TabsWidget/index.ts b/app/client/src/widgets/TabsWidget/index.ts index f672cedebc..1c5e1b644c 100644 --- a/app/client/src/widgets/TabsWidget/index.ts +++ b/app/client/src/widgets/TabsWidget/index.ts @@ -1,4 +1,5 @@ import { Colors } from "constants/Colors"; +import { WidgetHeightLimits } from "constants/WidgetConstants"; import { WidgetProps } from "widgets/BaseWidget"; import { BlueprintOperationTypes } from "widgets/constants"; import IconSVG from "./icon.svg"; @@ -16,12 +17,15 @@ export const CONFIG = { // define them in a Map which the platform understands to have // them stored only in the WidgetFactory. canvasHeightOffset: (props: WidgetProps): number => - props.shouldShowTabs === true ? 4 : 0, + props.shouldShowTabs === true ? 5 : 0, features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 1, + active: true, + }, }, defaults: { - rows: 40, + rows: WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS, columns: 24, shouldScrollContents: false, widgetName: "Tabs", diff --git a/app/client/src/widgets/TextWidget/index.ts b/app/client/src/widgets/TextWidget/index.ts index 6d54bb678d..a0e25720cf 100644 --- a/app/client/src/widgets/TextWidget/index.ts +++ b/app/client/src/widgets/TextWidget/index.ts @@ -5,7 +5,10 @@ import Widget from "./widget"; export const CONFIG = { features: { - dynamicHeight: true, + dynamicHeight: { + sectionIndex: 0, + active: true, + }, }, type: Widget.getWidgetType(), name: "Text", diff --git a/app/client/src/widgets/WidgetUtils.test.ts b/app/client/src/widgets/WidgetUtils.test.ts index 57a63abd16..148bb23daf 100644 --- a/app/client/src/widgets/WidgetUtils.test.ts +++ b/app/client/src/widgets/WidgetUtils.test.ts @@ -581,7 +581,7 @@ describe("Auto Height Utils", () => { expect(result).toBeUndefined(); }); - it("should return 4 if widget has AUTO_HEIGHT", () => { + it.skip("should return 4 if widget has AUTO_HEIGHT", () => { const props = { ...DUMMY_WIDGET, dynamicHeight: "AUTO_HEIGHT", @@ -612,7 +612,7 @@ describe("Auto Height Utils", () => { expect(result).toBe(WidgetHeightLimits.MIN_HEIGHT_IN_ROWS); }); - it("should return undefined if widget is FIXED ", () => { + it.skip("should return undefined if widget is FIXED ", () => { const props = { ...DUMMY_WIDGET, dynamicHeight: "FIXED", diff --git a/app/client/src/widgets/WidgetUtils.ts b/app/client/src/widgets/WidgetUtils.ts index 36dc99c2b0..413612850d 100644 --- a/app/client/src/widgets/WidgetUtils.ts +++ b/app/client/src/widgets/WidgetUtils.ts @@ -772,11 +772,7 @@ export function getWidgetMaxAutoHeight(props: WidgetProps) { * @returns: The min possible height of the widget (in rows) */ export function getWidgetMinAutoHeight(props: WidgetProps) { - if (props.dynamicHeight === DynamicHeight.AUTO_HEIGHT) { - return WidgetHeightLimits.MIN_HEIGHT_IN_ROWS; - } else if (props.dynamicHeight === DynamicHeight.AUTO_HEIGHT_WITH_LIMITS) { - return props.minDynamicHeight || WidgetHeightLimits.MIN_HEIGHT_IN_ROWS; - } + return props.minDynamicHeight || WidgetHeightLimits.MIN_HEIGHT_IN_ROWS; } /** diff --git a/app/client/src/widgets/withWidgetProps.tsx b/app/client/src/widgets/withWidgetProps.tsx index 5c58265807..17abaaccac 100644 --- a/app/client/src/widgets/withWidgetProps.tsx +++ b/app/client/src/widgets/withWidgetProps.tsx @@ -85,8 +85,11 @@ function withWidgetProps(WrappedWidget: typeof BaseWidget) { props.type === "CANVAS_WIDGET" && widgetId !== MAIN_CONTAINER_WIDGET_ID ) { + const isListWidgetCanvas = + props.noPad && props.dropDisabled && props.openParentPropertyPane; + widgetProps.rightColumn = props.rightColumn; - if (widgetProps.bottomRow === undefined) { + if (widgetProps.bottomRow === undefined || isListWidgetCanvas) { widgetProps.bottomRow = props.bottomRow; widgetProps.minHeight = props.minHeight; }