From c70892ba802b22c8136fc2e5c3996350477e5a13 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Wed, 26 Feb 2025 23:16:29 +0530 Subject: [PATCH 01/32] Fixed bug causing component definition to be copied on copying text --- frontend/src/AppBuilder/AppCanvas/appCanvasUtils.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/AppBuilder/AppCanvas/appCanvasUtils.js b/frontend/src/AppBuilder/AppCanvas/appCanvasUtils.js index 04ae6aa896..027734a6a1 100644 --- a/frontend/src/AppBuilder/AppCanvas/appCanvasUtils.js +++ b/frontend/src/AppBuilder/AppCanvas/appCanvasUtils.js @@ -240,6 +240,12 @@ const getSelectedText = () => { // TODO: Move this function to componentSlice export const copyComponents = ({ isCut = false, isCloning = false }) => { + const selectedText = window.getSelection()?.toString().trim(); + if (selectedText) { + navigator.clipboard.writeText(selectedText); + return; + } + const selectedComponents = useStore.getState().getSelectedComponentsDefinition(); if (selectedComponents.length < 1) return getSelectedText(); const allComponents = useStore.getState().getCurrentPageComponents(); From 161fffcb42785b4f8aef48ee9371c5a4a21e7756 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Thu, 27 Feb 2025 02:44:31 +0530 Subject: [PATCH 02/32] Automatically resizing codehinter input based on content --- .../QueryEditors/Restapi/TabContent.jsx | 4 ++-- .../TooljetDatabase/DropDownSelect.jsx | 4 +++- .../TooljetDatabase/JoinConstraint.jsx | 3 +-- .../TooljetDatabase/JoinSelect.jsx | 5 +---- .../QueryEditors/TooljetDatabase/JoinSort.jsx | 5 +---- .../TooljetDatabase/JoinTable.jsx | 3 +-- .../TooljetDatabase/RenderColumnUI.jsx | 5 +---- .../TooljetDatabase/RenderFilterSectionUI.jsx | 5 +---- .../TooljetDatabase/RenderSortUI.jsx | 5 +---- frontend/src/_styles/queryManager.scss | 21 +++++++++++++++++-- frontend/src/_styles/theme.scss | 1 + 11 files changed, 32 insertions(+), 29 deletions(-) diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx index cf47ded427..ee55937b1c 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx @@ -30,7 +30,7 @@ export default ({ return ( <>
-
+
) : ( -
+
{index > 0 && ( diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx index 4734addb26..863c826b8a 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx @@ -340,10 +340,7 @@ const JsonBfieldsForSelect = ({ selectedJsonbColumns, handleJSonChange, table }) handleRemove(colDetails.id, colDetails.name, colDetails.table)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx index 2d5a2de518..9e129e9eb4 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx @@ -164,10 +164,7 @@ export default function JoinSort({ darkMode }) { setJoinOrderByOptions(joinOrderByOptions.filter((opt, idx) => idx !== i))} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx index eba36f37a3..cf14448967 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx @@ -535,12 +535,11 @@ const RenderFilterSection = ({ darkMode }) => { removeFilterConditionEntry(index)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx index 1766691d66..89323c1c3c 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx @@ -54,10 +54,7 @@ const RenderColumnUI = ({ removeColumnOptionsPair(id)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx index 983019697a..cd7f94abf3 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx @@ -117,10 +117,7 @@ const RenderFilterSectionUI = ({ removeFilterConditionPair(id)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx index b5021974ba..a349b9e5ed 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx @@ -86,10 +86,7 @@ const RenderSortUI = ({ removeSortConditionPair(id)} > diff --git a/frontend/src/_styles/queryManager.scss b/frontend/src/_styles/queryManager.scss index 8a9eaf972a..ece491e06a 100644 --- a/frontend/src/_styles/queryManager.scss +++ b/frontend/src/_styles/queryManager.scss @@ -1851,8 +1851,9 @@ $border-radius: 4px; .tjdb-codhinter-wrapper{ .codehinter-input{ .cm-editor{ - height: 30px !important; + // height: 30px !important; min-height: 30px !important; + max-height:100px !important; border-radius: 0 !important; border-right: 0 ; } @@ -1860,8 +1861,9 @@ $border-radius: 4px; } .tjdb-limit-offset-codehinter{ .cm-editor{ - height: 30px !important; + // height: 30px !important; min-height: 30px !important; + max-height:100px !important; } } @@ -1899,4 +1901,19 @@ $border-radius: 4px; line-height: 18px; } } +} + + +.qm-delete-btn { + min-height: 30px; + height: 100% !important; + align-items: flex-start !important; + padding-top: 6px; +} + +.restapi-key-value { + .code-hinter-wrapper, .code-editor-basic-wrapper, .codehinter-container, .cm-codehinter, .code-editor-query-panel{ + height:100%; + max-height: 100px; + } } \ No newline at end of file diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss index c999eaa525..5a223dd733 100644 --- a/frontend/src/_styles/theme.scss +++ b/frontend/src/_styles/theme.scss @@ -15810,6 +15810,7 @@ tbody { } .rest-api-options-codehinter { + height: 100%; .cm-content>.cm-line { // max-width: 357px !important; } From 6952cd2292e79d36b127f247ec92949f6f70e598 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Sun, 2 Mar 2025 00:57:01 +0530 Subject: [PATCH 03/32] Fixed query panel resizing causing black bars issue --- .../src/AppBuilder/LeftSidebar/LeftSidebar.jsx | 14 ++++++++++---- frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx | 1 + frontend/src/_styles/left-sidebar.scss | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx b/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx index 4146c4a28e..aaf12714b9 100644 --- a/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx +++ b/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx @@ -34,6 +34,7 @@ export const BaseLeftSidebar = ({ resetUnreadErrorCount, toggleLeftSidebar, isSidebarOpen, + isDraggingQueryPane, ] = useStore( (state) => [ state.isLeftSideBarPinned, @@ -46,6 +47,7 @@ export const BaseLeftSidebar = ({ state.debugger.resetUnreadErrorCount, state.toggleLeftSidebar, state.isSidebarOpen, + state.queryPanel.isDraggingQueryPane, ], shallow ); @@ -68,11 +70,15 @@ export const BaseLeftSidebar = ({ }; useEffect(() => { - setPopoverContentHeight( - ((window.innerHeight - (queryPanelHeight == 0 ? 40 : queryPanelHeight) - 45) / window.innerHeight) * 100 - ); + if (!isDraggingQueryPane) { + setPopoverContentHeight( + ((window.innerHeight - (queryPanelHeight == 0 ? 40 : queryPanelHeight) - 45) / window.innerHeight) * 100 + ); + } else { + setPopoverContentHeight(100); + } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [queryPanelHeight]); + }, [queryPanelHeight, isDraggingQueryPane]); const renderPopoverContent = () => { if (selectedSidebarItem === null || !isSidebarOpen) return null; diff --git a/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx b/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx index 827efe6d33..ea8623b0c1 100644 --- a/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx +++ b/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx @@ -185,6 +185,7 @@ export const QueryPanel = ({ darkMode }) => { id="query-manager" style={{ height: `calc(100% - ${isExpanded ? height : 100}%)`, + maxHeight: '93.5%', cursor: isDraggingQueryPane || isTopOfQueryPanel ? 'row-resize' : 'default', ...(!isExpanded && { border: 'none', diff --git a/frontend/src/_styles/left-sidebar.scss b/frontend/src/_styles/left-sidebar.scss index 3f68e1486b..82b6762b54 100644 --- a/frontend/src/_styles/left-sidebar.scss +++ b/frontend/src/_styles/left-sidebar.scss @@ -701,6 +701,7 @@ .sidebar-h-100-popover { position: relative; height: 100vh; + overflow-y:scroll !important; margin-top: 0px; border-radius: 0px !important; From b4ff440e8705d56207cfa7e8fd8255af6dc5caaf Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Sun, 2 Mar 2025 13:09:56 +0530 Subject: [PATCH 04/32] Fixed popover values not saving when clicking on draggable items on inspector --- .../RightSideBar/Inspector/Components/Select.jsx | 5 +++++ .../RightSideBar/Inspector/Components/Table/Table.jsx | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx index a57c879121..d0b058b7b0 100644 --- a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx +++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx @@ -388,6 +388,11 @@ export function Select({ componentMeta, darkMode, ...restProps }) { placement="left" rootClose overlay={_renderOverlay(item, index)} + onToggle={(isOpen) => { + if (!isOpen) { + document.activeElement?.blur(); // Manually trigger blur when popover closes + } + }} >
this.setState({ showPopOver: showing })} + onToggle={(showing) => { + if (!showing) { + document.activeElement?.blur(); // Manually trigger blur when popover closes + } + this.setState({ showPopOver: showing }); + }} >
@@ -647,6 +652,7 @@ class TableComponent extends React.Component { if (show) { this.handleToggleColumnPopover(index); } else { + document.activeElement?.blur(); // Manually trigger blur when popover closes this.handleToggleColumnPopover(null); } }} From 3c68cd6f5a6c3b2fe390e5570b5afc7795ea99fb Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Mon, 3 Mar 2025 02:39:32 +0530 Subject: [PATCH 05/32] Code hinter issue fix --- .../src/AppBuilder/CodeEditor/PreviewBox.jsx | 16 ++- .../CodeEditor/SingleLineCodeEditor.jsx | 120 +++++++++++------- .../src/AppBuilder/CodeEditor/styles.scss | 5 + frontend/src/_styles/theme.scss | 7 +- 4 files changed, 99 insertions(+), 49 deletions(-) diff --git a/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx b/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx index 2429973c25..ce12c1b250 100644 --- a/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx +++ b/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx @@ -294,13 +294,9 @@ const PreviewContainer = ({ ...restProps }) => { const { validationSchema, isWorkspaceVariable, errorStateActive, previewPlacement, validationFn } = restProps; - const [errorMessage, setErrorMessage] = useState(''); - const typeofError = getCurrentNodeType(errorMessage); - const errorMsg = typeofError === 'Array' ? errorMessage[0] : errorMessage; - const darkMode = localStorage.getItem('darkMode') === 'true'; const popover = ( { + // Force position update on first render + // This is done to avoid scroll issue + if (state.elements.popper) { + state.elements.popper.style.position = 'fixed'; + } + }, }} > {(props) => React.cloneElement(popover, props)} diff --git a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx index 1243f26f43..98325df3a8 100644 --- a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx +++ b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx @@ -1,5 +1,5 @@ /* eslint-disable import/no-unresolved */ -import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { PreviewBox } from './PreviewBox'; import { ToolTip } from '@/Editor/Inspector/Elements/Components/ToolTip'; import { useTranslation } from 'react-i18next'; @@ -31,6 +31,7 @@ const SingleLineCodeEditor = ({ componentName, fieldMeta = {}, componentId, ...r const [currentValue, setCurrentValue] = useState(''); const [errorStateActive, setErrorStateActive] = useState(false); const [cursorInsidePreview, setCursorInsidePreview] = useState(false); + const [showSuggestions, setShowSuggestions] = useState(true); const validationFn = restProps?.validationFn; const componentDefinition = useStore((state) => state.getComponentDefinition(componentId), shallow); const parentId = componentDefinition?.component?.parent; @@ -38,6 +39,30 @@ const SingleLineCodeEditor = ({ componentName, fieldMeta = {}, componentId, ...r const customVariables = customResolvables?.[parentId]?.[0] || {}; + useEffect(() => { + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.intersectionRatio < 1) { + setShowPreview(false); + setShowSuggestions(false); + } else { + setShowSuggestions(true); + } + }, + { root: null, threshold: [1] } // Fires when any part of the element is out of view + ); + + if (wrapperRef.current) { + observer.observe(wrapperRef.current); + } + + return () => { + if (wrapperRef.current) { + observer.unobserve(wrapperRef.current); + } + }; + }, []); + const isPreviewFocused = useRef(false); const wrapperRef = useRef(null); @@ -136,6 +161,7 @@ const SingleLineCodeEditor = ({ componentName, fieldMeta = {}, componentId, ...r componentName={componentName} setShowPreview={setShowPreview} showPreview={showPreview} + showSuggestions={showSuggestions} {...restProps} />
@@ -168,6 +194,7 @@ const EditorInput = ({ previewRef, setShowPreview, onInputChange, + showSuggestions, }) => { const getSuggestions = useStore((state) => state.getSuggestions, shallow); function autoCompleteExtensionConfig(context) { @@ -223,7 +250,7 @@ const EditorInput = ({ defaultKeymap: true, positionInfo: () => { return { - class: 'cm-completionInfo-top cm-custom-completion-info', + class: 'cm-completionInfo-top cm-custom-completion-info cm-custom-singleline-completion-info', }; }, maxRenderedOptions: 10, @@ -339,15 +366,6 @@ const EditorInput = ({ data-cy={`${cyLabel}-input-field`} > {/* sticky element to position the preview box correctly on top without flowing out of container */} -
{usePortalEditor && ( - { - setFirstTimeFocus(false); - handleOnChange(val); - onInputChange && onInputChange(val); +
handleFocus()} - onBlur={() => handleOnBlur()} - className={customClassNames} - theme={theme} - indentWithTab={false} - readOnly={disabled} - /> + className="check-here" + ref={previewRef} + > + { + setFirstTimeFocus(false); + handleOnChange(val); + onInputChange && onInputChange(val); + }} + basicSetup={{ + lineNumbers: showLineNumbers, + syntaxHighlighting: true, + bracketMatching: true, + foldGutter: false, + highlightActiveLine: false, + autocompletion: showSuggestions, + completionKeymap: true, + searchKeymap: false, + }} + onMouseDown={() => handleFocus()} + onBlur={() => handleOnBlur()} + className={customClassNames} + theme={theme} + indentWithTab={false} + readOnly={disabled} + /> +
diff --git a/frontend/src/AppBuilder/CodeEditor/styles.scss b/frontend/src/AppBuilder/CodeEditor/styles.scss index c646fd30b1..73ba4ac36e 100644 --- a/frontend/src/AppBuilder/CodeEditor/styles.scss +++ b/frontend/src/AppBuilder/CodeEditor/styles.scss @@ -651,4 +651,9 @@ .cm-searchMatch.cm-searchMatch-selected { background-color: #F28F2D; +} + + +.cm-custom-singleline-completion-info { + display: none; } \ No newline at end of file diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss index c999eaa525..84b1d6dc80 100644 --- a/frontend/src/_styles/theme.scss +++ b/frontend/src/_styles/theme.scss @@ -1544,7 +1544,7 @@ button { .tab-content { overflow-y: auto; // TAB HEADER HEIGHT + FOOTER HEIGHT + Extra padding = 120px - height: calc(100vh - 7.5rem); + height: calc(100vh - 10.4rem); // Hide scrollbar -ms-overflow-style: none; /* IE and Edge */ @@ -18562,4 +18562,9 @@ section.ai-message-prompt-input-wrapper { margin-left: 8px; flex-grow: 1; } +} + + +.cm-tooltip { + z-index: 9999 !important; } \ No newline at end of file From 5e826c2f6fe60575760d6fd02f91fd59a09f8f78 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Mon, 3 Mar 2025 12:33:17 +0530 Subject: [PATCH 06/32] Dropdown breaking fix --- .../RightSideBar/Inspector/Components/Select.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx index d0b058b7b0..456b54cd02 100644 --- a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx +++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx @@ -297,7 +297,7 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
{options?.map((item, index) => { return ( - + {(provided, snapshot) => (
-
+
setHoveredOptionIndex(index)} @@ -406,7 +406,7 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
- {getResolvedValue(item.label)} + {getResolvedValue(item?.label)}
{index === hoveredOptionIndex && ( From 49c2a5b5a8a759fe78fb80eaa2d546e4f18098f6 Mon Sep 17 00:00:00 2001 From: devanshu052000 Date: Tue, 18 Feb 2025 21:58:59 +0530 Subject: [PATCH 07/32] Fix: Application crash on startup due to invalid query parameters --- frontend/src/_helpers/utils.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/frontend/src/_helpers/utils.js b/frontend/src/_helpers/utils.js index 07f0b6dccb..7373260691 100644 --- a/frontend/src/_helpers/utils.js +++ b/frontend/src/_helpers/utils.js @@ -242,18 +242,20 @@ export function resolveReferences( } else { const dynamicVariables = getDynamicVariables(object); - for (const dynamicVariable of dynamicVariables) { - const value = resolveString( - dynamicVariable, - state, - customObjects, - reservedKeyword, - withError, - forPreviewBox - ); + if (dynamicVariables) { + for (const dynamicVariable of dynamicVariables) { + const value = resolveString( + dynamicVariable, + state, + customObjects, + reservedKeyword, + withError, + forPreviewBox + ); - if (typeof value !== 'function') { - object = object.replace(dynamicVariable, value); + if (typeof value !== 'function') { + object = object.replace(dynamicVariable, value); + } } } } From 154927404baf6b8553be9df326ad3162d3b4720e Mon Sep 17 00:00:00 2001 From: Nakul Nagargade Date: Thu, 6 Mar 2025 15:18:40 +0530 Subject: [PATCH 08/32] Fix alignment issues arising due to label width setting for input components --- frontend/src/_ui/Label.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/_ui/Label.jsx b/frontend/src/_ui/Label.jsx index 3cd7f886cb..721ac05203 100644 --- a/frontend/src/_ui/Label.jsx +++ b/frontend/src/_ui/Label.jsx @@ -13,6 +13,7 @@ function Label({ label, width, labelRef, color, defaultAlignment, direction, aut justifyContent: direction == 'right' ? 'flex-end' : 'flex-start', fontSize: '12px', height: defaultAlignment === 'top' && '20px', + overflow: 'hidden', }} >

Date: Tue, 18 Feb 2025 01:24:23 +0530 Subject: [PATCH 09/32] feat: added method for unsetting all page and global variables --- frontend/src/AppBuilder/CodeBuilder/utils.js | 2 ++ .../AppBuilder/_stores/slices/eventsSlice.js | 28 +++++++++++++++++ .../_stores/slices/resolvedSlice.js | 30 +++++++++++++++++++ frontend/src/AppBuilder/_stores/utils.js | 2 ++ frontend/src/Editor/ActionTypes.js | 9 ++++++ 5 files changed, 71 insertions(+) diff --git a/frontend/src/AppBuilder/CodeBuilder/utils.js b/frontend/src/AppBuilder/CodeBuilder/utils.js index 7a75bdb3b8..be3674aa1f 100644 --- a/frontend/src/AppBuilder/CodeBuilder/utils.js +++ b/frontend/src/AppBuilder/CodeBuilder/utils.js @@ -74,6 +74,7 @@ export function getSuggestionKeys(refState) { 'setVariable', 'getVariable', 'unSetVariable', + 'unsetAllVariables', 'showAlert', 'logout', 'showModal', @@ -85,6 +86,7 @@ export function getSuggestionKeys(refState) { 'setPageVariable', 'getPageVariable', 'unsetPageVariable', + 'unsetAllPageVariables', 'switchPage', ]; diff --git a/frontend/src/AppBuilder/_stores/slices/eventsSlice.js b/frontend/src/AppBuilder/_stores/slices/eventsSlice.js index 948ac39b39..995050d023 100644 --- a/frontend/src/AppBuilder/_stores/slices/eventsSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/eventsSlice.js @@ -690,6 +690,12 @@ export const createEventsSlice = (set, get) => ({ return getVariable(key); } + case 'unset-all-custom-variables': { + const { unsetAllVariables } = get(); + unsetAllVariables(); + return Promise.resolve(); + } + case 'unset-custom-variable': { const { unsetVariable } = get(); const key = getResolvedValue(event.key, customVariables); @@ -746,6 +752,12 @@ export const createEventsSlice = (set, get) => ({ return getPageVariable(key); } + case 'unset-all-page-variables': { + const { unsetAllPageVariables } = get(); + unsetAllPageVariables(); + return Promise.resolve(); + } + case 'unset-page-variable': { const { unsetPageVariable } = get(); const key = getResolvedValue(event.key, customVariables); @@ -953,6 +965,13 @@ export const createEventsSlice = (set, get) => ({ } }; + const unsetAllVariables = () => { + const event = { + actionId: 'unset-all-custom-variables', + }; + return executeAction(event, mode, {}); + }; + const unSetVariable = (key = '') => { if (key) { const event = { @@ -1066,6 +1085,13 @@ export const createEventsSlice = (set, get) => ({ return executeAction(event, mode, {}); }; + const unsetAllPageVariables = () => { + const event = { + actionId: 'unset-all-page-variables', + }; + return executeAction(event, mode, {}); + }; + const unsetPageVariable = (key = '') => { const event = { actionId: 'unset-page-variable', @@ -1133,6 +1159,7 @@ export const createEventsSlice = (set, get) => ({ runQuery, setVariable, getVariable, + unsetAllVariables, unSetVariable, showAlert, logout, @@ -1144,6 +1171,7 @@ export const createEventsSlice = (set, get) => ({ generateFile, setPageVariable, getPageVariable, + unsetAllPageVariables, unsetPageVariable, switchPage, logInfo, diff --git a/frontend/src/AppBuilder/_stores/slices/resolvedSlice.js b/frontend/src/AppBuilder/_stores/slices/resolvedSlice.js index ebbd524fd1..b76c8b072d 100644 --- a/frontend/src/AppBuilder/_stores/slices/resolvedSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/resolvedSlice.js @@ -140,6 +140,21 @@ export const createResolvedSlice = (set, get) => ({ get().updateDependencyValues(`variables.${key}`); }, + unsetAllVariables: (moduleId = 'canvas') => { + const variables = get().resolvedStore.modules[moduleId].exposedValues.variables; + set( + (state) => { + state.resolvedStore.modules[moduleId].exposedValues.variables = {}; + }, + false, + 'unsetAllVariables' + ); + Object.keys(variables).forEach((key) => { + get().removeNode(`variables.${key}`); + get().updateDependencyValues(`variables.${key}`); + }); + }, + // page.variables setPageVariable: (key, value, moduleId = 'canvas') => { set( @@ -167,6 +182,21 @@ export const createResolvedSlice = (set, get) => ({ get().updateDependencyValues(`page.variables.${key}`); }, + unsetAllPageVariables: (moduleId = 'canvas') => { + const pageVariables = get().resolvedStore.modules[moduleId].exposedValues.page.variables; + set( + (state) => { + state.resolvedStore.modules[moduleId].exposedValues.page.variables = {}; + }, + false, + 'unsetAllPageVariables' + ); + Object.keys(pageVariables).forEach((key) => { + get().removeNode(`page.variables.${key}`); + get().updateDependencyValues(`page.variables.${key}`); + }); + }, + setResolvedQuery: (queryId, details, moduleId = 'canvas') => { set( (state) => { diff --git a/frontend/src/AppBuilder/_stores/utils.js b/frontend/src/AppBuilder/_stores/utils.js index bb08c620da..33e50eb9cc 100644 --- a/frontend/src/AppBuilder/_stores/utils.js +++ b/frontend/src/AppBuilder/_stores/utils.js @@ -473,6 +473,7 @@ export function createReferencesLookup(currentState, forQueryParams = false, ini const actions = [ 'runQuery', 'setVariable', + 'unsetAllVariables', 'unSetVariable', 'showAlert', 'logout', @@ -483,6 +484,7 @@ export function createReferencesLookup(currentState, forQueryParams = false, ini 'goToApp', 'generateFile', 'setPageVariable', + 'unsetAllPageVariables', 'unsetPageVariable', 'switchPage', 'logInfo', diff --git a/frontend/src/Editor/ActionTypes.js b/frontend/src/Editor/ActionTypes.js index 01b0a34759..0bad71b3ac 100644 --- a/frontend/src/Editor/ActionTypes.js +++ b/frontend/src/Editor/ActionTypes.js @@ -78,6 +78,10 @@ export const ActionTypes = [ { name: 'value', type: 'code', default: '' }, ], }, + { + name: 'Unset all variables', + id: 'unset-all-custom-variables', + }, { name: 'Unset variable', id: 'unset-custom-variable', @@ -96,6 +100,10 @@ export const ActionTypes = [ { name: 'value', type: 'code', default: '' }, ], }, + { + name: 'Unset all page variables', + id: 'unset-all-page-variables', + }, { name: 'Unset page variable', id: 'unset-page-variable', @@ -104,6 +112,7 @@ export const ActionTypes = [ { name: 'value', type: 'code', default: '' }, ], }, + { name: 'Control component', id: 'control-component', From 8c0e2c9396daa76fa95f7eed8aa7eb29cccaf5e9 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Fri, 21 Feb 2025 02:22:14 +0530 Subject: [PATCH 10/32] Fixed transformation issue causing query to not retain multiple transformation types --- .../Components/Transformation.jsx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/frontend/src/AppBuilder/QueryManager/Components/Transformation.jsx b/frontend/src/AppBuilder/QueryManager/Components/Transformation.jsx index 52178043cf..2234fa8e50 100644 --- a/frontend/src/AppBuilder/QueryManager/Components/Transformation.jsx +++ b/frontend/src/AppBuilder/QueryManager/Components/Transformation.jsx @@ -108,7 +108,8 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende const [codeEditorKey, setCodeEditorKey] = useState(uuidv4()); const [state, setState] = useState({ ...defaultValue, - [options.transformationLanguage ?? 'javascript']: options?.transformation, + ...(options?.transformation ? { [options.transformationLanguage ?? 'javascript']: options?.transformation } : {}), + ...options?.transformations, }); const { t } = useTranslation(); @@ -119,7 +120,6 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende useEffect(() => { if (lang !== (options.transformationLanguage ?? 'javascript')) { changeOption('transformationLanguage', lang); - changeOption('transformation', state[lang]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [lang]); @@ -127,20 +127,24 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende useEffect(() => { if (prevQueryId.current === queryId) { lang !== (options.transformationLanguage ?? 'javascript') && changeOption('transformationLanguage', lang); - setState({ ...state, [lang]: options.transformation ?? state[lang] ?? defaultValue[lang] }); + setState((prevState) => { + return { + ...prevState, + ...(options?.transformation + ? { [options.transformationLanguage ?? 'javascript']: options?.transformation } + : {}), + ...options?.transformations, + }; + }); } prevQueryId.current = queryId; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [JSON.stringify(options.transformation)]); + }, [JSON.stringify(options?.transformation || {}), JSON.stringify(options.transformations)]); useEffect(() => { if (selectedQueryId !== queryId) { - const nonLangdefaultCode = getNonActiveTransformations(options?.transformationLanguage ?? 'javascript'); - const finalState = _.merge( - {}, - { [options?.transformationLanguage ?? lang]: options.transformation ?? defaultValue[lang] }, - nonLangdefaultCode - ); + const olderTransformation = options?.transformation ? { [lang]: options?.transformation } : {}; + const finalState = _.merge({}, defaultValue, olderTransformation, options?.transformations); setState(finalState); } @@ -206,8 +210,6 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende activeKey={lang} onSelect={(value) => { setLang(value); - changeOption('transformationLanguage', value); - changeOption('transformation', state[value]); }} defaultActiveKey="javascript" > @@ -250,7 +252,7 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende height={400} className="query-hinter" onChange={(value) => { - changeOption('transformation', value); + changeOption('transformations', { ...state, [lang]: value }); }} renderCopilot={renderCopilot} componentName={`transformation`} From 064953b7501a506127c6cb14642381b37572b94e Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Mon, 3 Mar 2025 23:17:37 +0530 Subject: [PATCH 11/32] Fixed issue causing field is empty error to popup on 0 --- frontend/src/AppBuilder/_stores/slices/componentsSlice.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/AppBuilder/_stores/slices/componentsSlice.js b/frontend/src/AppBuilder/_stores/slices/componentsSlice.js index 702bb8dfcc..1cd904efe2 100644 --- a/frontend/src/AppBuilder/_stores/slices/componentsSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/componentsSlice.js @@ -502,7 +502,7 @@ export const createComponentsSlice = (set, get) => ({ const resolvedMandatory = getResolvedValue(mandatory, customResolveObjects) || false; - if (resolvedMandatory == true && !widgetValue) { + if (resolvedMandatory == true && !widgetValue && widgetValue !== 0) { return { isValid: false, validationError: `Field cannot be empty`, From 3c4f9a1c7a09fc80a24104b87e1207daaeeaff9f Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Tue, 4 Mar 2025 16:32:19 +0530 Subject: [PATCH 12/32] Button group csa added --- .../WidgetManager/widgets/buttonGroup.js | 7 +++++ .../src/Editor/Components/ButtonGroup.jsx | 29 +++++++++++++++++++ .../services/widget-config/buttonGroup.js | 8 +++++ 3 files changed, 44 insertions(+) diff --git a/frontend/src/AppBuilder/WidgetManager/widgets/buttonGroup.js b/frontend/src/AppBuilder/WidgetManager/widgets/buttonGroup.js index c0fa889dd5..ab3eb40c2c 100644 --- a/frontend/src/AppBuilder/WidgetManager/widgets/buttonGroup.js +++ b/frontend/src/AppBuilder/WidgetManager/widgets/buttonGroup.js @@ -127,6 +127,13 @@ export const buttonGroupConfig = { exposedVariables: { selected: [1], }, + actions: [ + { + handle: 'setSelected', + displayName: 'Select option', + params: [{ handle: 'selected', displayName: 'Value' }], + }, + ], definition: { others: { showOnDesktop: { value: '{{true}}' }, diff --git a/frontend/src/Editor/Components/ButtonGroup.jsx b/frontend/src/Editor/Components/ButtonGroup.jsx index 7364348271..a9526576ff 100644 --- a/frontend/src/Editor/Components/ButtonGroup.jsx +++ b/frontend/src/Editor/Components/ButtonGroup.jsx @@ -66,6 +66,35 @@ export const ButtonGroup = function Button({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [multiSelection]); + const setSelected = (selected) => { + if (multiSelection) { + if (Array.isArray(selected)) { + const filteredItems = selected.filter((item) => values.includes(item)); + setDefaultActive(filteredItems); + setExposedVariable('selected', filteredItems.join(',')); + } else if ((typeof selected === 'string' || typeof selected === 'number') && values.includes(selected)) { + setDefaultActive([selected]); + setExposedVariable('selected', String(selected)); + } + } else { + if (Array.isArray(selected)) { + const filteredItems = selected.filter((item) => values.includes(item)); + console.log('filterdItems', filteredItems); + if (filteredItems?.length >= 1) { + setDefaultActive([filteredItems[0]]); + setExposedVariable('selected', String(filteredItems[0])); + } + } else if ((typeof selected === 'string' || typeof selected === 'number') && values.includes(selected)) { + setDefaultActive([selected]); + setExposedVariable('selected', String(selected)); + } + } + }; + + useEffect(() => { + setExposedVariable('setSelected', setSelected); + }, [multiSelection]); + const buttonClick = (index) => { if (defaultActive?.includes(values[index]) && multiSelection) { const copyDefaultActive = [...defaultActive]; diff --git a/server/src/modules/apps/services/widget-config/buttonGroup.js b/server/src/modules/apps/services/widget-config/buttonGroup.js index c0fa889dd5..4523a98bb7 100644 --- a/server/src/modules/apps/services/widget-config/buttonGroup.js +++ b/server/src/modules/apps/services/widget-config/buttonGroup.js @@ -127,6 +127,14 @@ export const buttonGroupConfig = { exposedVariables: { selected: [1], }, + actions: [ + { + handle: 'setSelected', + displayName: 'Select option', + params: [{ handle: 'selected', displayName: 'Value' }], + }, + ], + definition: { others: { showOnDesktop: { value: '{{true}}' }, From 791b60a17e7565d8d5e0cfc2fcfc17eaa8542011 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Tue, 4 Mar 2025 19:58:43 +0530 Subject: [PATCH 13/32] Small issue fix --- frontend/src/Editor/Components/ButtonGroup.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/Editor/Components/ButtonGroup.jsx b/frontend/src/Editor/Components/ButtonGroup.jsx index a9526576ff..67618a61ab 100644 --- a/frontend/src/Editor/Components/ButtonGroup.jsx +++ b/frontend/src/Editor/Components/ButtonGroup.jsx @@ -79,7 +79,6 @@ export const ButtonGroup = function Button({ } else { if (Array.isArray(selected)) { const filteredItems = selected.filter((item) => values.includes(item)); - console.log('filterdItems', filteredItems); if (filteredItems?.length >= 1) { setDefaultActive([filteredItems[0]]); setExposedVariable('selected', String(filteredItems[0])); @@ -93,7 +92,7 @@ export const ButtonGroup = function Button({ useEffect(() => { setExposedVariable('setSelected', setSelected); - }, [multiSelection]); + }, [multiSelection, values]); const buttonClick = (index) => { if (defaultActive?.includes(values[index]) && multiSelection) { From 1d83543abf4784d70d98984c027d6695c24a14ec Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Sun, 2 Mar 2025 13:09:56 +0530 Subject: [PATCH 14/32] Fixed popover values not saving when clicking on draggable items on inspector --- .../RightSideBar/Inspector/Components/Select.jsx | 5 +++++ .../RightSideBar/Inspector/Components/Table/Table.jsx | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx index db52205467..cb5065efda 100644 --- a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx +++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx @@ -386,6 +386,11 @@ export function Select({ componentMeta, darkMode, ...restProps }) { placement="left" rootClose overlay={_renderOverlay(item, index)} + onToggle={(isOpen) => { + if (!isOpen) { + document.activeElement?.blur(); // Manually trigger blur when popover closes + } + }} >

this.setState({ showPopOver: showing })} + onToggle={(showing) => { + if (!showing) { + document.activeElement?.blur(); // Manually trigger blur when popover closes + } + this.setState({ showPopOver: showing }); + }} >
@@ -647,6 +652,7 @@ class TableComponent extends React.Component { if (show) { this.handleToggleColumnPopover(index); } else { + document.activeElement?.blur(); // Manually trigger blur when popover closes this.handleToggleColumnPopover(null); } }} From 6d8f00557fc7372a40b3ae42bc5402d29712402b Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Mon, 3 Mar 2025 12:33:17 +0530 Subject: [PATCH 15/32] Dropdown breaking fix --- .../RightSideBar/Inspector/Components/Select.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx index cb5065efda..ded481fadb 100644 --- a/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx +++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Components/Select.jsx @@ -295,7 +295,7 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
{options?.map((item, index) => { return ( - + {(provided, snapshot) => (
-
+
setHoveredOptionIndex(index)} @@ -404,7 +404,7 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
- {getResolvedValue(item.label)} + {getResolvedValue(item?.label)}
{index === hoveredOptionIndex && ( From 293c3d7939fac977fb5f610d73f5c9f2d7285654 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Sun, 2 Mar 2025 00:57:01 +0530 Subject: [PATCH 16/32] Fixed query panel resizing causing black bars issue --- .../src/AppBuilder/LeftSidebar/LeftSidebar.jsx | 14 ++++++++++---- frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx | 1 + frontend/src/_styles/left-sidebar.scss | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx b/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx index 4146c4a28e..aaf12714b9 100644 --- a/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx +++ b/frontend/src/AppBuilder/LeftSidebar/LeftSidebar.jsx @@ -34,6 +34,7 @@ export const BaseLeftSidebar = ({ resetUnreadErrorCount, toggleLeftSidebar, isSidebarOpen, + isDraggingQueryPane, ] = useStore( (state) => [ state.isLeftSideBarPinned, @@ -46,6 +47,7 @@ export const BaseLeftSidebar = ({ state.debugger.resetUnreadErrorCount, state.toggleLeftSidebar, state.isSidebarOpen, + state.queryPanel.isDraggingQueryPane, ], shallow ); @@ -68,11 +70,15 @@ export const BaseLeftSidebar = ({ }; useEffect(() => { - setPopoverContentHeight( - ((window.innerHeight - (queryPanelHeight == 0 ? 40 : queryPanelHeight) - 45) / window.innerHeight) * 100 - ); + if (!isDraggingQueryPane) { + setPopoverContentHeight( + ((window.innerHeight - (queryPanelHeight == 0 ? 40 : queryPanelHeight) - 45) / window.innerHeight) * 100 + ); + } else { + setPopoverContentHeight(100); + } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [queryPanelHeight]); + }, [queryPanelHeight, isDraggingQueryPane]); const renderPopoverContent = () => { if (selectedSidebarItem === null || !isSidebarOpen) return null; diff --git a/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx b/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx index 827efe6d33..ea8623b0c1 100644 --- a/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx +++ b/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx @@ -185,6 +185,7 @@ export const QueryPanel = ({ darkMode }) => { id="query-manager" style={{ height: `calc(100% - ${isExpanded ? height : 100}%)`, + maxHeight: '93.5%', cursor: isDraggingQueryPane || isTopOfQueryPanel ? 'row-resize' : 'default', ...(!isExpanded && { border: 'none', diff --git a/frontend/src/_styles/left-sidebar.scss b/frontend/src/_styles/left-sidebar.scss index 3f68e1486b..82b6762b54 100644 --- a/frontend/src/_styles/left-sidebar.scss +++ b/frontend/src/_styles/left-sidebar.scss @@ -701,6 +701,7 @@ .sidebar-h-100-popover { position: relative; height: 100vh; + overflow-y:scroll !important; margin-top: 0px; border-radius: 0px !important; From ecd9055090dbbef63154555722ac01ae10ef23a7 Mon Sep 17 00:00:00 2001 From: Nakul Nagargade Date: Fri, 7 Mar 2025 21:48:04 +0530 Subject: [PATCH 17/32] fix --- frontend/src/_ui/Label.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/_ui/Label.jsx b/frontend/src/_ui/Label.jsx index 721ac05203..443f4ddc6e 100644 --- a/frontend/src/_ui/Label.jsx +++ b/frontend/src/_ui/Label.jsx @@ -13,7 +13,7 @@ function Label({ label, width, labelRef, color, defaultAlignment, direction, aut justifyContent: direction == 'right' ? 'flex-end' : 'flex-start', fontSize: '12px', height: defaultAlignment === 'top' && '20px', - overflow: 'hidden', + overflow: auto ? 'visible' : 'hidden', }} >

Date: Tue, 11 Mar 2025 12:54:46 +0530 Subject: [PATCH 18/32] fix child component image widget width not correct --- frontend/src/AppBuilder/WidgetManager/widgets/listview.js | 1 + frontend/src/AppBuilder/WidgetManager/widgets/tabs.js | 1 + frontend/src/Editor/WidgetManager/configs/listview.js | 1 + frontend/src/Editor/WidgetManager/configs/tabs.js | 1 + server/src/modules/apps/services/widget-config/listview.js | 1 + server/src/modules/apps/services/widget-config/tabs.js | 1 + 6 files changed, 6 insertions(+) diff --git a/frontend/src/AppBuilder/WidgetManager/widgets/listview.js b/frontend/src/AppBuilder/WidgetManager/widgets/listview.js index fec2e812b4..62b55a7fea 100644 --- a/frontend/src/AppBuilder/WidgetManager/widgets/listview.js +++ b/frontend/src/AppBuilder/WidgetManager/widgets/listview.js @@ -13,6 +13,7 @@ export const listviewConfig = { top: 15, left: 3, height: 100, + width: 7, }, properties: ['source'], accessorKey: 'imageURL', diff --git a/frontend/src/AppBuilder/WidgetManager/widgets/tabs.js b/frontend/src/AppBuilder/WidgetManager/widgets/tabs.js index a397979a3e..0ed1e2a320 100644 --- a/frontend/src/AppBuilder/WidgetManager/widgets/tabs.js +++ b/frontend/src/AppBuilder/WidgetManager/widgets/tabs.js @@ -13,6 +13,7 @@ export const tabsConfig = { top: 60, left: 17, height: 100, + width: 7, }, tab: 0, properties: ['source'], diff --git a/frontend/src/Editor/WidgetManager/configs/listview.js b/frontend/src/Editor/WidgetManager/configs/listview.js index 25da8f73c6..86825142eb 100644 --- a/frontend/src/Editor/WidgetManager/configs/listview.js +++ b/frontend/src/Editor/WidgetManager/configs/listview.js @@ -13,6 +13,7 @@ export const listviewConfig = { top: 15, left: 3, height: 100, + width: 7, }, properties: ['source'], accessorKey: 'imageURL', diff --git a/frontend/src/Editor/WidgetManager/configs/tabs.js b/frontend/src/Editor/WidgetManager/configs/tabs.js index a397979a3e..0ed1e2a320 100644 --- a/frontend/src/Editor/WidgetManager/configs/tabs.js +++ b/frontend/src/Editor/WidgetManager/configs/tabs.js @@ -13,6 +13,7 @@ export const tabsConfig = { top: 60, left: 17, height: 100, + width: 7, }, tab: 0, properties: ['source'], diff --git a/server/src/modules/apps/services/widget-config/listview.js b/server/src/modules/apps/services/widget-config/listview.js index d710babbf0..fc8cd749ed 100644 --- a/server/src/modules/apps/services/widget-config/listview.js +++ b/server/src/modules/apps/services/widget-config/listview.js @@ -13,6 +13,7 @@ export const listviewConfig = { top: 15, left: 3, height: 100, + width: 7, }, properties: ['source'], accessorKey: 'imageURL', diff --git a/server/src/modules/apps/services/widget-config/tabs.js b/server/src/modules/apps/services/widget-config/tabs.js index a397979a3e..0ed1e2a320 100644 --- a/server/src/modules/apps/services/widget-config/tabs.js +++ b/server/src/modules/apps/services/widget-config/tabs.js @@ -13,6 +13,7 @@ export const tabsConfig = { top: 60, left: 17, height: 100, + width: 7, }, tab: 0, properties: ['source'], From fd36e3447026730393645f1c6b2c6b32967c669f Mon Sep 17 00:00:00 2001 From: Nakul Nagargade Date: Tue, 11 Mar 2025 13:08:52 +0530 Subject: [PATCH 19/32] fix in listview and kanban, confighandle is appearing for subcontainer child widgets --- .../AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx | 9 +++++---- frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx b/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx index bb4d4fc69b..84d31bc6ac 100644 --- a/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx +++ b/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx @@ -14,6 +14,7 @@ export const ConfigHandle = ({ showHandle, componentType, visibility, + subContainerIndex, }) => { const shouldFreeze = useStore((state) => state.getShouldFreeze()); const componentName = useStore((state) => state.getComponentDefinition(id)?.component?.name || '', shallow); @@ -35,12 +36,12 @@ export const ConfigHandle = ({ const anyComponentHovered = state.getHoveredComponentForGrid() !== '' || state.hoveredComponentBoundaryId !== ''; // If one component is hovered and one is selected, show the handle for the hovered component return ( - isWidgetHovered || - (showHandle && - (!isMultipleComponentsSelected || (isModal && isModalOpen)) && - !anyComponentHovered) + (subContainerIndex === 0 || subContainerIndex === null) && + (isWidgetHovered || + (showHandle && (!isMultipleComponentsSelected || (isModal && isModalOpen)) && !anyComponentHovered)) ); }, shallow); + let height = visibility === false ? 10 : widgetHeight; return ( diff --git a/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx b/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx index f583ebb53a..7758f29b68 100644 --- a/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx +++ b/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx @@ -90,6 +90,7 @@ const WidgetWrapper = memo( showHandle={isWidgetActive} componentType={componentType} visibility={visibility} + subContainerIndex={subContainerIndex} /> )} Date: Wed, 12 Mar 2025 11:26:05 +0530 Subject: [PATCH 20/32] Fix visibility and disable variables naming conventions --- frontend/src/Editor/Components/TextInput.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/frontend/src/Editor/Components/TextInput.jsx b/frontend/src/Editor/Components/TextInput.jsx index 29fbaaa625..ce482947a9 100644 --- a/frontend/src/Editor/Components/TextInput.jsx +++ b/frontend/src/Editor/Components/TextInput.jsx @@ -236,8 +236,6 @@ export const TextInput = function TextInput({ value: properties.value, isMandatory: isMandatory, isLoading: loading, - isVisible: visibility, - isDisabled: disable, }; setExposedVariables(exposedVariables); @@ -245,6 +243,17 @@ export const TextInput = function TextInput({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + // Fix for "visibility is not defined" in production because there's a naming conflict in the code. + // The issue is in the exposedVariables object where we had both a function named visibility and a property isVisible that depends on the state variable with the same name. + const exposedVariables = { + isVisible: visibility, + isDisabled: disable, + }; + setExposedVariables(exposedVariables); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const setInputValue = (value) => { setValue(value); setExposedVariable('value', value); From dcee09564cbac28f98abdd833dd5efa72a596c64 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Tue, 18 Mar 2025 11:11:49 +0530 Subject: [PATCH 21/32] Adding single image changes from ee lts (#12272) --- docker/ee/ee-production.Dockerfile | 51 ++++++++++++++++++++++++++++++ server/entrypoint.sh | 47 +++++++++++++++++++-------- 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/docker/ee/ee-production.Dockerfile b/docker/ee/ee-production.Dockerfile index 230a2f8ebb..b69458daa1 100644 --- a/docker/ee/ee-production.Dockerfile +++ b/docker/ee/ee-production.Dockerfile @@ -62,8 +62,40 @@ FROM debian:11 RUN apt-get update -yq \ && apt-get install curl gnupg zip -yq \ && apt-get install -yq build-essential \ + && apt -y install redis \ && apt-get clean -y +# Install required dependencies for downloading and extracting files +RUN apt-get update && apt-get install -y \ + curl tar xz-utils postgresql postgresql-contrib postgresql-client && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install PostgREST from official Docker image +COPY --from=postgrest/postgrest:v12.2.0 /bin/postgrest /bin + +RUN apt-get update && apt-get install -y supervisor + +# Create supervisord configuration file +RUN echo "[supervisord]\n" \ + "nodaemon=true\n" \ + "\n" \ + "[program:postgrest]\n" \ + "command=/bin/postgrest \n" \ + "autostart=true\n" \ + "autorestart=true\n" \ + "stdout_logfile=/dev/stdout\n" \ + "stderr_logfile=/dev/stderr\n" \ + "stdout_logfile_maxbytes=0\n" \ + "stderr_logfile_maxbytes=0\n" \ + "\n" | sed 's/ //' > /etc/supervisor/conf.d/supervisord.conf + +# Create a wrapper for PostgREST to prefix its logs +RUN mv /bin/postgrest /bin/postgrest-original && \ + echo '#!/bin/bash\n\ +exec /bin/postgrest-original "$@" 2>&1 | sed "s/^/[PostgREST] /"\n\ +' > /bin/postgrest && \ + chmod +x /bin/postgrest + RUN curl -O https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz \ && tar -xf node-v18.18.2-linux-x64.tar.xz \ @@ -152,6 +184,25 @@ RUN mkdir -p /tmp/.npm/npm-cache/_logs \ && chmod g+s /tmp/.npm/npm-cache/_logs \ && chmod -R g=u /tmp/.npm/npm-cache/_logs +# Create Redis data, log, and configuration directories +RUN mkdir -p /var/lib/redis /var/log/redis /etc/redis \ + && chown -R appuser:0 /var/lib/redis /var/log/redis /etc/redis \ + && chmod g+s /var/lib/redis /var/log/redis /etc/redis \ + && chmod -R g=u /var/lib/redis /var/log/redis /etc/redis + +# Set permissions for PostgREST binary +RUN chown appuser:0 /bin/postgrest && chmod u+x /bin/postgrest && chmod g=u /bin/postgrest + +RUN touch /tmp/postgrest.conf \ + && chown appuser:0 /tmp/postgrest.conf \ + && chmod 640 /tmp/postgrest.conf + +# Create PostgREST data, log, and configuration directories +RUN mkdir -p /var/lib/postgrest /var/log/postgrest /etc/postgrest \ + && chown -R appuser:0 /var/lib/postgrest /var/log/postgrest /etc/postgrest \ + && chmod g+s /var/lib/postgrest /var/log/postgrest /etc/postgrest \ + && chmod -R g=u /var/lib/postgrest /var/log/postgrest /etc/postgrest + ENV HOME=/home/appuser # Switch back to appuser diff --git a/server/entrypoint.sh b/server/entrypoint.sh index ba321cd401..ac4b0bafd2 100755 --- a/server/entrypoint.sh +++ b/server/entrypoint.sh @@ -8,6 +8,40 @@ if [ -f "./.env" ]; then export $(grep -v '^#' ./.env | xargs -d '\n') || true fi +# Start Redis server only if REDIS_HOST is localhost or not set +if [ -z "$REDIS_HOST" ] || [ "$REDIS_HOST" = "localhost" ]; then + echo "Starting Redis server locally..." + redis-server /etc/redis/redis.conf & +elif [ -n "$REDIS_URL" ]; then + echo "REDIS_URL connection is set: $REDIS_URL" +else + echo "Using external Redis at $REDIS_HOST:$REDIS_PORT." + + # Validate external Redis connection + if ! ./server/scripts/wait-for-it.sh "$REDIS_HOST:${REDIS_PORT:-6379}" --strict --timeout=300 -- echo "Redis is up"; then + echo "Error: Unable to connect to Redis at $REDIS_HOST:$REDIS_PORT." + exit 1 + fi +fi + +# Check if PGRST_HOST starts with "localhost" +if [[ "$PGRST_HOST" == localhost:* ]]; then + echo "Starting PostgREST server locally..." + + # Generate PostgREST configuration in a writable directory + POSTGREST_CONFIG_PATH="/tmp/postgrest.conf" + + echo "db-uri = \"${PGRST_DB_URI}\"" > "$POSTGREST_CONFIG_PATH" + echo "db-pre-config = \"postgrest.pre_config\"" >> "$POSTGREST_CONFIG_PATH" + echo "server-port = \"${PGRST_SERVER_PORT}\"" >> "$POSTGREST_CONFIG_PATH" + + # Starting PostgREST + echo "Starting PostgREST..." + postgrest "$POSTGREST_CONFIG_PATH" & +else + echo "Using external PostgREST at $PGRST_HOST." +fi + # Check WORKLOW_WORKER and skip SETUP_CMD if true if [ "${WORKFLOW_WORKER}" == "true" ]; then echo "WORKFLOW_WORKER is set to true. Running worker process." @@ -31,19 +65,6 @@ else ./server/scripts/wait-for-it.sh "$PG_HOST:$PG_PORT" --strict --timeout=300 -- echo "PostgreSQL is up" fi -# Note: This Redis connection check changes are only for EE repo - -# Check Redis connection -if [ -z "$REDIS_URL" ]; then - if [ -z "$REDIS_HOST" ] || [ -z "$REDIS_PORT" ]; then - echo "Waiting for Redis connection..." - fi - - ./server/scripts/wait-for-it.sh $REDIS_HOST:${REDIS_PORT:-6379} --strict --timeout=300 -- echo "Redis is up" -else - echo "REDIS_URL connection is set" -fi - # Run setup command if defined if [ -n "$SETUP_CMD" ]; then $SETUP_CMD From faeb817c99d381dd75e51bafaea75e31e8e2aed8 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Tue, 18 Mar 2025 12:45:55 +0530 Subject: [PATCH 22/32] Table suggestions getting cropped & previewPlacement fix --- frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx | 2 +- .../RightSideBar/Inspector/Components/Table/Table.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx b/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx index ce12c1b250..6c28bdbb21 100644 --- a/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx +++ b/frontend/src/AppBuilder/CodeEditor/PreviewBox.jsx @@ -419,7 +419,7 @@ const PreviewContainer = ({ <> {!isPortalOpen && ( From ac09c2cfd6af61fd5a36fd89422d1ccef310983e Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Thu, 27 Feb 2025 02:44:31 +0530 Subject: [PATCH 23/32] Automatically resizing codehinter input based on content --- .../QueryEditors/Restapi/TabContent.jsx | 4 ++-- .../TooljetDatabase/DropDownSelect.jsx | 4 +++- .../TooljetDatabase/JoinConstraint.jsx | 3 +-- .../TooljetDatabase/JoinSelect.jsx | 5 +---- .../QueryEditors/TooljetDatabase/JoinSort.jsx | 5 +---- .../TooljetDatabase/JoinTable.jsx | 3 +-- .../TooljetDatabase/RenderColumnUI.jsx | 5 +---- .../TooljetDatabase/RenderFilterSectionUI.jsx | 5 +---- .../TooljetDatabase/RenderSortUI.jsx | 5 +---- frontend/src/_styles/queryManager.scss | 21 +++++++++++++++++-- frontend/src/_styles/theme.scss | 1 + 11 files changed, 32 insertions(+), 29 deletions(-) diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx index cf47ded427..ee55937b1c 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/TabContent.jsx @@ -30,7 +30,7 @@ export default ({ return ( <>

-
+
) : ( -
+
{index > 0 && ( diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx index 4734addb26..863c826b8a 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSelect.jsx @@ -340,10 +340,7 @@ const JsonBfieldsForSelect = ({ selectedJsonbColumns, handleJSonChange, table }) handleRemove(colDetails.id, colDetails.name, colDetails.table)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx index 2d5a2de518..9e129e9eb4 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinSort.jsx @@ -164,10 +164,7 @@ export default function JoinSort({ darkMode }) { setJoinOrderByOptions(joinOrderByOptions.filter((opt, idx) => idx !== i))} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx index eba36f37a3..cf14448967 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/JoinTable.jsx @@ -535,12 +535,11 @@ const RenderFilterSection = ({ darkMode }) => { removeFilterConditionEntry(index)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx index 1766691d66..89323c1c3c 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderColumnUI.jsx @@ -54,10 +54,7 @@ const RenderColumnUI = ({ removeColumnOptionsPair(id)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx index 983019697a..cd7f94abf3 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderFilterSectionUI.jsx @@ -117,10 +117,7 @@ const RenderFilterSectionUI = ({ removeFilterConditionPair(id)} > diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx index b5021974ba..a349b9e5ed 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/RenderSortUI.jsx @@ -86,10 +86,7 @@ const RenderSortUI = ({ removeSortConditionPair(id)} > diff --git a/frontend/src/_styles/queryManager.scss b/frontend/src/_styles/queryManager.scss index 7b256c3812..1c63a111e9 100644 --- a/frontend/src/_styles/queryManager.scss +++ b/frontend/src/_styles/queryManager.scss @@ -1856,8 +1856,9 @@ $border-radius: 4px; .tjdb-codhinter-wrapper{ .codehinter-input{ .cm-editor{ - height: 30px !important; + // height: 30px !important; min-height: 30px !important; + max-height:100px !important; border-radius: 0 !important; border-right: 0 ; } @@ -1865,8 +1866,9 @@ $border-radius: 4px; } .tjdb-limit-offset-codehinter{ .cm-editor{ - height: 30px !important; + // height: 30px !important; min-height: 30px !important; + max-height:100px !important; } } @@ -1904,4 +1906,19 @@ $border-radius: 4px; line-height: 18px; } } +} + + +.qm-delete-btn { + min-height: 30px; + height: 100% !important; + align-items: flex-start !important; + padding-top: 6px; +} + +.restapi-key-value { + .code-hinter-wrapper, .code-editor-basic-wrapper, .codehinter-container, .cm-codehinter, .code-editor-query-panel{ + height:100%; + max-height: 100px; + } } \ No newline at end of file diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss index ff2e935de6..886d0a64c2 100644 --- a/frontend/src/_styles/theme.scss +++ b/frontend/src/_styles/theme.scss @@ -15824,6 +15824,7 @@ tbody { } .rest-api-options-codehinter { + height: 100%; .cm-content>.cm-line { // max-width: 357px !important; } From 86a871109b2a482cade5f57af08edec95f14ac96 Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Tue, 18 Mar 2025 13:40:18 +0530 Subject: [PATCH 24/32] Max height fix --- frontend/src/_styles/theme.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss index 886d0a64c2..2f86a4c280 100644 --- a/frontend/src/_styles/theme.scss +++ b/frontend/src/_styles/theme.scss @@ -18632,3 +18632,10 @@ section.ai-message-prompt-input-wrapper { } } } + + +.single-line-codehinter-input { + .cm-editor { + max-height: 100px !important; + } +} \ No newline at end of file From 12febbd7163e58a2d5c15d2a9ea18e36f7a74d0d Mon Sep 17 00:00:00 2001 From: Shaurya Sharma Date: Tue, 18 Mar 2025 14:42:48 +0530 Subject: [PATCH 25/32] Max height fix --- frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx index 98325df3a8..cad5556eea 100644 --- a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx +++ b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx @@ -313,7 +313,7 @@ const EditorInput = ({ const isInsideQueryPane = !!currentEditorHeightRef?.current?.closest('.query-details'); const showLineNumbers = lang == 'jsx' || type === 'extendedSingleLine' || false; - const customClassNames = cx('codehinter-input', { + const customClassNames = cx('codehinter-input single-line-codehinter-input', { 'border-danger': error, focused: isFocused, 'focus-box-shadow-active': firstTimeFocus, From 0c338412a8c054ad9a5f9b8b4a11a61bf78077df Mon Sep 17 00:00:00 2001 From: Mekhla Asopa <59684099+Mekhla-Asopa@users.noreply.github.com> Date: Wed, 19 Mar 2025 13:56:33 +0530 Subject: [PATCH 26/32] added data-cy for rest api (#12298) --- .../CodeEditor/SingleLineCodeEditor.jsx | 2 +- frontend/src/_components/DynamicForm.jsx | 4 +- .../src/_components/EncyrptedFieldWrapper.jsx | 3 +- frontend/src/_ui/Accordion/AccordionItem.js | 34 ++++++++++++----- frontend/src/_ui/HttpHeaders/SourceEditor.jsx | 8 +++- frontend/src/_ui/HttpHeaders/index.js | 26 ++++++++----- frontend/src/_ui/OAuth/Authentication.jsx | 5 ++- frontend/src/_ui/OAuth/GrantTypes.jsx | 37 ++++++++++++------- frontend/src/_ui/Search/Search.jsx | 2 +- .../DataSourceManager/DataSourceManager.jsx | 3 +- 10 files changed, 86 insertions(+), 38 deletions(-) diff --git a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx index 1243f26f43..5506a94fed 100644 --- a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx +++ b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx @@ -336,7 +336,7 @@ const EditorInput = ({
{/* sticky element to position the preview box correctly on top without flowing out of container */}
{!isSpecificComponent && ( @@ -628,6 +629,7 @@ const DynamicForm = ({ {...getElementProps(obj[key])} {...computedProps[propertyKey]} data-cy={`${String(label).toLocaleLowerCase().replace(/\s+/g, '-')}-text-field`} + dataCy={obj[key].key.replace(/_/g, '-')} //to be removed after whole ui is same isHorizontalLayout={isHorizontalLayout} /> @@ -669,7 +671,7 @@ const DynamicForm = ({ )} -
+
keyValuePairValueChanged(e.target.value, 0, index)} @@ -47,6 +50,7 @@ export default ({ />