diff --git a/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx b/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx index 1c218596b1..d580016912 100644 --- a/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx +++ b/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx @@ -87,7 +87,7 @@ export const AppCanvas = ({ moduleId, appId, isViewerSidebarPinned }) => { }} className={`app-${appId}`} > - + {creationMode === 'GIT' && } {creationMode !== 'GIT' && } diff --git a/frontend/src/AppBuilder/AppCanvas/AutoComputeMobileLayoutAlert.jsx b/frontend/src/AppBuilder/AppCanvas/AutoComputeMobileLayoutAlert.jsx index 4290c2e8db..a36209e525 100644 --- a/frontend/src/AppBuilder/AppCanvas/AutoComputeMobileLayoutAlert.jsx +++ b/frontend/src/AppBuilder/AppCanvas/AutoComputeMobileLayoutAlert.jsx @@ -10,7 +10,7 @@ import useConfirm from '@/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/C import { diff } from 'deep-object-diff'; import { isEmpty } from 'lodash'; -export default function AutoComputeMobileLayoutAlert({ currentLayout }) { +export default function AutoComputeMobileLayoutAlert({ currentLayout, darkMode }) { const currentPageComponents = useStore((state) => state.getCurrentPageComponents(), shallow); const isAutoMobileLayout = useStore((state) => state.getIsAutoMobileLayout(), shallow); const turnOffAutoComputeLayout = useStore((state) => state.turnOffAutoComputeLayout, shallow); @@ -67,7 +67,7 @@ export default function AutoComputeMobileLayoutAlert({ currentLayout }) { } return ( <> - +
{ const shouldFreeze = useStore((state) => state.getShouldFreeze()); const componentName = useStore((state) => state.getComponentDefinition(id)?.component?.name || '', shallow); @@ -23,11 +24,12 @@ export const ConfigHandle = ({ shallow ); const deleteComponents = useStore((state) => state.deleteComponents, shallow); + let height = visibility === false ? 10 : widgetHeight; return (
{ + const selectedComponents = getSelectedComponents(); + if (selectedComponents.length > 0) { + setWidgetDeleteConfirmation(true); + } + }; + useEffect(() => { const handleClick = (e) => { const modalContainer = document.getElementById('modal-container'); @@ -91,7 +98,7 @@ export const HotkeyProvider = ({ children, mode, currentLayout, canvasMaxWidth } handleEscapeKeyPress(); // clears the selected components break; case 'Backspace': - setWidgetDeleteConfirmation(true); // Delete opration -> First asks for a Confirmation + deleteComponents(); // Delete opration -> First asks for a Confirmation break; case 'KeyD': copyComponents({ isCloning: true }); // Clone/Duplicate operation diff --git a/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx b/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx index ccaa6fefe7..e7d02c7393 100644 --- a/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx +++ b/frontend/src/AppBuilder/AppCanvas/WidgetWrapper.jsx @@ -89,6 +89,7 @@ const WidgetWrapper = memo( widgetHeight={layoutData.height} showHandle={isWidgetActive} componentType={componentType} + visibility={visibility} /> )} { for (let selectedComponent of filteredSelectedComponents) { if (addedComponentId.has(selectedComponent.id)) continue; - const events = useStore.getState().eventsSlice.geEventsByComponentsId(selectedComponent.id); + const events = useStore.getState().eventsSlice.getEventsByComponentsId(selectedComponent.id); const component = { component: allComponents[selectedComponent.id]?.component, layouts: allComponents[selectedComponent.id]?.layouts, diff --git a/frontend/src/AppBuilder/CodeEditor/autocompleteExtensionConfig.js b/frontend/src/AppBuilder/CodeEditor/autocompleteExtensionConfig.js index 3a4f2cf38e..e1d597c957 100644 --- a/frontend/src/AppBuilder/CodeEditor/autocompleteExtensionConfig.js +++ b/frontend/src/AppBuilder/CodeEditor/autocompleteExtensionConfig.js @@ -124,9 +124,7 @@ export const generateHints = (hints, totalReferences = 1, input, searchText) => const multiReferenceInSingleIndentifier = totalReferences == 1 && searchText !== currentWord; if (multiReferenceInSingleIndentifier) { - const splitAtSearchString = doc.toString().split(searchText)[0]; - const newFrom = splitAtSearchString.length; - + const newFrom = to - searchText.length; pickedCompletionConfig.from = newFrom; } else if (totalReferences > 1 && completion.type !== 'js_methods') { const splitIndex = from; diff --git a/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx b/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx index e82777856f..c4c820ff69 100644 --- a/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx +++ b/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx @@ -311,7 +311,6 @@ export const QueryManagerBody = ({ darkMode, options, setOptions, activeTab }) = ); }; - if (selectedQueryId !== selectedQuery?.id) return; const hasPermissions = selectedDataSource?.scope === 'global' && selectedDataSource?.type !== DATA_SOURCE_TYPE.SAMPLE ? canUpdateDataSource(selectedQuery?.data_source_id) || diff --git a/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx b/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx index f10477bd6b..827efe6d33 100644 --- a/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx +++ b/frontend/src/AppBuilder/QueryPanel/QueryPanel.jsx @@ -76,9 +76,15 @@ export const QueryPanel = ({ darkMode }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [windowSize.height, isExpanded, isWindowResizing]); - const onMouseDown = useCallback(() => { - if (isTopOfQueryPanel) setIsDraggingQueryPane(true); - }, [isTopOfQueryPanel]); + const onMouseDown = useCallback( + (e) => { + if (isTopOfQueryPanel) { + e.preventDefault(); + setIsDraggingQueryPane(true); + } + }, + [isTopOfQueryPanel] + ); const onMouseUp = useCallback((e) => { setIsDraggingQueryPane(false); diff --git a/frontend/src/AppBuilder/Widgets/Listview.jsx b/frontend/src/AppBuilder/Widgets/Listview.jsx index 5f5ddac261..5ec5abbb17 100644 --- a/frontend/src/AppBuilder/Widgets/Listview.jsx +++ b/frontend/src/AppBuilder/Widgets/Listview.jsx @@ -143,6 +143,8 @@ export const Listview = function Listview({ if (selectedRowIndex != undefined) { exposedVariables.selectedRecordId = selectedRowIndex; exposedVariables.selectedRecord = childrenData[selectedRowIndex]; + exposedVariables.selectedRowId = selectedRowIndex; + exposedVariables.selectedRow = childrenData[selectedRowIndex]; } setExposedVariables(exposedVariables); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -252,7 +254,7 @@ export const Listview = function Listview({ style={{ position: 'relative', height: `${rowHeight}px`, width: `${100 / positiveColumns}%` }} key={index} // data-cy={`${String(component.name).toLowerCase()}-row-${index}`} - onClick={(event) => { + onClickCapture={(event) => { onRecordOrRowClicked(index); }} > diff --git a/frontend/src/AppBuilder/_stores/slices/componentsSlice.js b/frontend/src/AppBuilder/_stores/slices/componentsSlice.js index 19b278421a..bd50c02335 100644 --- a/frontend/src/AppBuilder/_stores/slices/componentsSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/componentsSlice.js @@ -741,7 +741,9 @@ export const createComponentsSlice = (set, get) => ({ if (!state.containerChildrenMapping[parentId]) { state.containerChildrenMapping[parentId] = []; } - state.containerChildrenMapping[parentId].push(newComponent.id); + if (!state.containerChildrenMapping[parentId].includes(newComponent.id)) { + state.containerChildrenMapping[parentId].push(newComponent.id); + } const page = state.modules[moduleId].pages[state.currentPageIndex]; page.components[newComponent.id] = newComponent; }, skipUndoRedo), diff --git a/frontend/src/AppBuilder/_stores/slices/dataQuerySlice.js b/frontend/src/AppBuilder/_stores/slices/dataQuerySlice.js index 4da379f443..802fd4f0f1 100644 --- a/frontend/src/AppBuilder/_stores/slices/dataQuerySlice.js +++ b/frontend/src/AppBuilder/_stores/slices/dataQuerySlice.js @@ -223,6 +223,8 @@ export const createDataQuerySlice = (set, get) => ({ set((state) => { state.dataQuery.creatingQueryInProcessId = uuidv4(); }); + const { eventsSlice } = get(); + const { getEventsByComponentsId, createAppVersionEventHandlers } = eventsSlice; const dataQueries = get().dataQuery.queries.modules[moduleId]; const queryToClone = { ...dataQueries.find((query) => query.id === id) }; let newName = queryToClone.name + '_copy'; @@ -266,6 +268,20 @@ export const createDataQuerySlice = (set, get) => ({ rawData: [], id: data.id, }); + + const events = getEventsByComponentsId(queryToClone.id); + + events.forEach((event) => { + const newEvent = { + event: { + ...event.event, + }, + eventType: event.target, + attachedTo: data.id, + index: event.index, + }; + createAppVersionEventHandlers(newEvent, moduleId); + }); }) .catch((error) => { console.error('error', error); diff --git a/frontend/src/AppBuilder/_stores/slices/eventsSlice.js b/frontend/src/AppBuilder/_stores/slices/eventsSlice.js index 336bc06953..02ee8fc29c 100644 --- a/frontend/src/AppBuilder/_stores/slices/eventsSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/eventsSlice.js @@ -948,7 +948,7 @@ export const createEventsSlice = (set, get) => ({ }; }, // Selectors - geEventsByComponentsId: (componentId, moduleId = 'canvas') => { + getEventsByComponentsId: (componentId, moduleId = 'canvas') => { const { eventsSlice } = get(); return eventsSlice.module[moduleId]?.events?.filter((event) => event.sourceId === componentId); }, diff --git a/frontend/src/Editor/Components/Chart.jsx b/frontend/src/Editor/Components/Chart.jsx index 3491b4d051..d9080679b4 100644 --- a/frontend/src/Editor/Components/Chart.jsx +++ b/frontend/src/Editor/Components/Chart.jsx @@ -103,11 +103,13 @@ export const Chart = function Chart({ color: fontColor, }, }, + showlegend: chartLayout.showlegend ?? false, legend: { text: chartTitle, font: { color: fontColor, }, + ...chartLayout.legend, }, xaxis: { showgrid: showGridLines, diff --git a/frontend/src/Editor/Components/DropdownV2/DropdownV2.jsx b/frontend/src/Editor/Components/DropdownV2/DropdownV2.jsx index 9b1c5981e0..a4b318eadf 100644 --- a/frontend/src/Editor/Components/DropdownV2/DropdownV2.jsx +++ b/frontend/src/Editor/Components/DropdownV2/DropdownV2.jsx @@ -440,6 +440,7 @@ export const DropdownV2 = ({ auto={labelAutoWidth} isMandatory={isMandatory} _width={_width} + top={'1px'} />