From f65bd433db7bfd80cab9f3350feb219abd109f59 Mon Sep 17 00:00:00 2001 From: Manish Kushare <37823141+manishkushare@users.noreply.github.com> Date: Thu, 6 Jun 2024 13:03:15 +0530 Subject: [PATCH 1/5] Fix : Target and actions section getting overlap in fk drawer (#9996) * Target and actions section getting overlap in fk drawer * Updated the solution --- frontend/src/TooljetDatabase/Forms/TableKeyRelations.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/TooljetDatabase/Forms/TableKeyRelations.jsx b/frontend/src/TooljetDatabase/Forms/TableKeyRelations.jsx index 9ec2422059..5d1db94e3c 100644 --- a/frontend/src/TooljetDatabase/Forms/TableKeyRelations.jsx +++ b/frontend/src/TooljetDatabase/Forms/TableKeyRelations.jsx @@ -265,7 +265,7 @@ function SourceKeyRelation({ onTableClick={false} /> -
+
From 9596425208c8513a8871b901c65134e55eca015b Mon Sep 17 00:00:00 2001 From: Akshay Sasidharan Date: Wed, 29 May 2024 15:10:15 +0530 Subject: [PATCH 2/5] make all datasource options expicit --- .../plugins/salesforce/lib/manifest.json | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/marketplace/plugins/salesforce/lib/manifest.json b/marketplace/plugins/salesforce/lib/manifest.json index 48e9d63afc..9130a71004 100644 --- a/marketplace/plugins/salesforce/lib/manifest.json +++ b/marketplace/plugins/salesforce/lib/manifest.json @@ -13,11 +13,31 @@ "rawData": {} }, "options": { - "api_version":{ - "type":"string" + "client_id": { + "type": "string" }, - "redirect_url":{ - "type":"string" + "client_secret": { + "type": "string", + "encrypted": true + }, + "code": { + "type": "string", + "encrypted": true + }, + "redirect_url": { + "type": "string" + }, + "api_version": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "oauth2": { + "type": "boolean" + }, + "plugin_id": { + "type": "string" } }, "customTesting": true, @@ -38,4 +58,4 @@ }, "required": [] -} \ No newline at end of file +} From 147d58c44079ff5f7cc7488402aade054423cdd8 Mon Sep 17 00:00:00 2001 From: Parth <108089718+parthy007@users.noreply.github.com> Date: Fri, 31 May 2024 18:16:58 +0530 Subject: [PATCH 3/5] Fix: Disable resource-name inputs for all action types and change placeholder for resource-body (#9946) * Disable resource-name input and change placeholder text in resource-body * Format the placeholder text * Remove space from placeholder --- frontend/src/Editor/CodeEditor/CodeHinter.jsx | 4 +++- .../CodeEditor/SingleLineCodeEditor.jsx | 5 ++++- frontend/src/Editor/CodeEditor/styles.scss | 7 ++++++ frontend/src/_components/DynamicForm.jsx | 2 ++ marketplace/plugins/salesforce/lib/index.ts | 9 ++++---- .../plugins/salesforce/lib/operations.json | 22 +++++++++---------- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/frontend/src/Editor/CodeEditor/CodeHinter.jsx b/frontend/src/Editor/CodeEditor/CodeHinter.jsx index b3a491a334..0629f52149 100644 --- a/frontend/src/Editor/CodeEditor/CodeHinter.jsx +++ b/frontend/src/Editor/CodeEditor/CodeHinter.jsx @@ -18,7 +18,7 @@ const CODE_EDITOR_TYPE = { extendedSingleLine: SingleLineCodeEditor, }; -const CodeHinter = ({ type = 'basic', initialValue, componentName, ...restProps }) => { +const CodeHinter = ({ type = 'basic', initialValue, componentName, disabled, ...restProps }) => { const { suggestions } = useResolveStore( (state) => ({ suggestions: state.suggestions, @@ -75,6 +75,7 @@ const CodeHinter = ({ type = 'basic', initialValue, componentName, ...restProps forceUpdate, }} componentName={componentName} + disabled={disabled} {...restProps} /> ); @@ -136,6 +137,7 @@ CodeHinter.DepericatedAlert = DepericatedAlertForWorkspaceVariable; CodeHinter.propTypes = { type: PropTypes.string.isRequired, + disabled: PropTypes.bool, }; export default CodeHinter; diff --git a/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx b/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx index b20bb63f9e..fad2684660 100644 --- a/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx +++ b/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx @@ -136,6 +136,7 @@ const EditorInput = ({ type, delayOnChange = true, // Added this prop to immediately update the onBlurUpdate callback paramLabel = '', + disabled = false, }) => { function autoCompleteExtensionConfig(context) { let word = context.matchBefore(/\w*/); @@ -224,6 +225,7 @@ const EditorInput = ({ focused: isFocused, 'focus-box-shadow-active': firstTimeFocus, 'widget-code-editor': componentId, + 'disabled-pointerevents': disabled, }); const currentEditorHeightRef = useRef(null); @@ -241,7 +243,7 @@ const EditorInput = ({ return (
{usePortalEditor && ( @@ -292,6 +294,7 @@ const EditorInput = ({ className={customClassNames} theme={theme} indentWithTab={true} + readOnly={disabled} /> diff --git a/frontend/src/Editor/CodeEditor/styles.scss b/frontend/src/Editor/CodeEditor/styles.scss index e63c817f2e..f224014f38 100644 --- a/frontend/src/Editor/CodeEditor/styles.scss +++ b/frontend/src/Editor/CodeEditor/styles.scss @@ -531,4 +531,11 @@ max-width: 100% !important; } } +} + +.disabled-cursor{ + cursor: not-allowed; +} +.disabled-pointerevents{ + pointer-events: none; } \ No newline at end of file diff --git a/frontend/src/_components/DynamicForm.jsx b/frontend/src/_components/DynamicForm.jsx index b8f6ef91f3..bb9dae0228 100644 --- a/frontend/src/_components/DynamicForm.jsx +++ b/frontend/src/_components/DynamicForm.jsx @@ -195,6 +195,7 @@ const DynamicForm = ({ encrypted, editorType = 'basic', placeholders = {}, + disabled = false, }) => { const source = schema?.source?.kind; const darkMode = localStorage.getItem('darkMode') === 'true'; @@ -340,6 +341,7 @@ const DynamicForm = ({ componentName: queryName ? `${queryName}::${key ?? ''}` : null, cyLabel: key ? `${String(key).toLocaleLowerCase().replace(/\s+/g, '-')}` : '', delayOnChange: false, + disabled, }; case 'react-component-openapi-validator': return { diff --git a/marketplace/plugins/salesforce/lib/index.ts b/marketplace/plugins/salesforce/lib/index.ts index 1c442321bf..d6e7a3b7d6 100644 --- a/marketplace/plugins/salesforce/lib/index.ts +++ b/marketplace/plugins/salesforce/lib/index.ts @@ -38,28 +38,27 @@ export default class Salesforce implements QueryService { } case 'crud': { const actiontype = queryOptions.actiontype; - const resource_name = queryOptions.resource_name; const resource_id = queryOptions.resource_id; const resource_body = queryOptions.resource_body; switch (actiontype) { case 'retrieve': - response = await conn.sobject(resource_name).retrieve(resource_id); + response = await conn.sobject('Account').retrieve(resource_id); result = response; break; case 'create': - response = await conn.sobject(resource_name).create(resource_body); + response = await conn.sobject('Account').create(resource_body); result = response; break; case 'update': - response = await conn.sobject(resource_name).update({ Id: resource_id, ...resource_body }); + response = await conn.sobject('Account').update({ Id: resource_id, ...resource_body }); result = response; break; case 'delete': - response = await conn.sobject(resource_name).destroy(resource_id); + response = await conn.sobject('Account').destroy(resource_id); result = response; break; diff --git a/marketplace/plugins/salesforce/lib/operations.json b/marketplace/plugins/salesforce/lib/operations.json index b1c6858813..f975d8c02b 100644 --- a/marketplace/plugins/salesforce/lib/operations.json +++ b/marketplace/plugins/salesforce/lib/operations.json @@ -73,24 +73,19 @@ "resource_name": { "label": "Resource Name", "key": "resource_name", - "type": "dropdown", + "type": "codehinter", "lineNumbers": false, "height": "36px", "className": "codehinter-plugins", "placeholder": "Account", - "list": [ - { - "value": "Account", - "name": "Account" - } - ] + "disabled": true }, "resource_body": { "label": "Resource Body", "key": "resource_body", "type": "codehinter", "lineNumbers": true, - "placeholder": "{{ name : “ToolJet” }}", + "placeholder": "{{ {name: “ToolJet”} }}", "description": "Enter the resource body", "height": "100px" } @@ -103,13 +98,14 @@ "lineNumbers": false, "height": "36px", "className": "codehinter-plugins", - "placeholder": "Account" + "placeholder": "Account", + "disabled": true }, "resource_body": { "label": "Resource Body", "key": "resource_body", "type": "codehinter", - "placeholder": "{{ Id:”0012F3E4R56487900N” , name : “ToolJet” }}", + "placeholder": "{{ {Id:”0012F3E4R56487900N”, name: “ToolJet”} }}", "description": "Enter the resource body", "height": "100px" } @@ -122,7 +118,8 @@ "lineNumbers": false, "height": "36px", "className": "codehinter-plugins", - "placeholder": "Account" + "placeholder": "Account", + "disabled": true }, "resource_id": { "label": "Resource ID", @@ -143,7 +140,8 @@ "lineNumbers": false, "height": "36px", "className": "codehinter-plugins", - "placeholder": "Account" + "placeholder": "Account", + "disabled": true }, "resource_id": { "label": "Resource ID", From 30c3378e3e8ef156d1c681cc1e67c4f2034512b6 Mon Sep 17 00:00:00 2001 From: Akshay Sasidharan Date: Thu, 6 Jun 2024 13:15:54 +0530 Subject: [PATCH 4/5] bump to v2.50.3 --- .version | 2 +- frontend/.version | 2 +- server/.version | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.version b/.version index 555bd6c928..57c32dea2e 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.50.2 +2.50.3 diff --git a/frontend/.version b/frontend/.version index 555bd6c928..57c32dea2e 100644 --- a/frontend/.version +++ b/frontend/.version @@ -1 +1 @@ -2.50.2 +2.50.3 diff --git a/server/.version b/server/.version index 555bd6c928..57c32dea2e 100644 --- a/server/.version +++ b/server/.version @@ -1 +1 @@ -2.50.2 +2.50.3 From 8675b3186a6a55d9dbcbb352ddbd45bfbea67d64 Mon Sep 17 00:00:00 2001 From: Kiran Ashok Date: Thu, 6 Jun 2024 17:19:46 +0530 Subject: [PATCH 5/5] Bugfixes: Table crash fixes for LTS / Zindex issue for datepicker (#9984) * fix : Table breaking for nested array of objects * fix : table crash on selecting time only datepicker sing add new row * remove logs * update zindex * Fix: Entity reference mapping and performance issues on codehinter (#10004) * Fix: Entity reference mapping and performance issues on codehinter (#430) * trial * fixes: - entity mapping on version switch - entity mapping on page switch - entity mapping on viewer on page switch * fixes: performance of codehinter for rendering nested json data * trial * fixes: - entity mapping on version switch - entity mapping on page switch - entity mapping on viewer on page switch * Revert "fixes:" This reverts commit 6ca9921731468aca4132c0aff3aeba02845bcd8a. * Revert "trial" This reverts commit 5bfa40c36aeb84abe98c0f2ab2418148772a048d. * fixes: editor crash on resolving workspace variables * fixes: populate JS hints * chore : version bump * version bump --------- Co-authored-by: Arpit --- .version | 2 +- frontend/.version | 2 +- frontend/src/Editor/CodeEditor/PreviewBox.jsx | 32 +++++++--- .../CodeEditor/SingleLineCodeEditor.jsx | 1 + frontend/src/Editor/CodeEditor/utils.js | 41 ++++++++---- .../Editor/Components/Table/Datepicker.jsx | 2 +- frontend/src/Editor/Components/Table/Link.jsx | 2 +- .../src/Editor/Components/Table/String.jsx | 11 ++-- frontend/src/Editor/Components/Table/Tags.jsx | 3 +- frontend/src/Editor/Components/Table/Text.jsx | 2 +- .../Editor/Components/Table/columns/index.jsx | 6 +- frontend/src/Editor/Container.jsx | 1 + frontend/src/Editor/Editor.jsx | 62 ++++++++++++++----- frontend/src/Editor/Viewer.jsx | 25 +++++++- frontend/src/_helpers/editorHelpers.js | 5 +- frontend/src/_stores/currentStateStore.js | 3 +- frontend/src/_stores/resolverStore.js | 2 +- server/.version | 2 +- 18 files changed, 142 insertions(+), 62 deletions(-) diff --git a/.version b/.version index 57c32dea2e..ed23763f45 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.50.3 +2.50.4 diff --git a/frontend/.version b/frontend/.version index 57c32dea2e..ed23763f45 100644 --- a/frontend/.version +++ b/frontend/.version @@ -1 +1 @@ -2.50.3 +2.50.4 diff --git a/frontend/src/Editor/CodeEditor/PreviewBox.jsx b/frontend/src/Editor/CodeEditor/PreviewBox.jsx index 61ac9dfc27..2a5d0884c5 100644 --- a/frontend/src/Editor/CodeEditor/PreviewBox.jsx +++ b/frontend/src/Editor/CodeEditor/PreviewBox.jsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { computeCoercion, getCurrentNodeType, resolveReferences } from './utils'; +import { computeCoercion, getCurrentNodeType, hasDeepChildren, resolveReferences } from './utils'; import CodeHinter from '.'; import { copyToClipboard } from '@/_helpers/appUtils'; import { Alert } from '@/_ui/Alert/Alert'; @@ -17,6 +17,7 @@ export const PreviewBox = ({ setErrorStateActive, setErrorMessage, customVariables, + isWorkspaceVariable, }) => { const [resolvedValue, setResolvedValue] = useState(''); const [error, setError] = useState(null); @@ -68,7 +69,7 @@ export const PreviewBox = ({ useEffect(() => { const [valid, _error, newValue, resolvedValue] = resolveReferences(currentValue, validationSchema, customVariables); - if (!validationSchema || isEmpty(validationSchema)) { + if (isWorkspaceVariable || !validationSchema || isEmpty(validationSchema)) { return setResolvedValue(newValue); } @@ -115,6 +116,7 @@ export const PreviewBox = ({ resolvedValue={content} coersionData={coersionData} withValidation={!isEmpty(validationSchema)} + isWorkspaceVariable={isWorkspaceVariable} /> copyToClipboard(error ? error?.value : content)} @@ -125,7 +127,14 @@ export const PreviewBox = ({ ); }; -const RenderResolvedValue = ({ error, previewType, resolvedValue, coersionData, withValidation }) => { +const RenderResolvedValue = ({ + error, + previewType, + resolvedValue, + coersionData, + withValidation, + isWorkspaceVariable, +}) => { const computeCoersionPreview = (resolvedValue, coersionData) => { if (coersionData?.typeBeforeCoercion === coersionData?.typeAfterCoercion) return resolvedValue; @@ -140,12 +149,13 @@ const RenderResolvedValue = ({ error, previewType, resolvedValue, coersionData, return resolvedValue + coersionData?.coercionPreview; }; - const previewValueType = - withValidation || (coersionData && coersionData?.typeBeforeCoercion) - ? `${coersionData?.typeBeforeCoercion} ${ - coersionData?.coercionPreview ? ` → ${coersionData?.typeAfterCoercion}` : '' - }` - : previewType; + const previewValueType = isWorkspaceVariable + ? previewType + : withValidation || (coersionData && coersionData?.typeBeforeCoercion) + ? `${coersionData?.typeBeforeCoercion} ${ + coersionData?.coercionPreview ? ` → ${coersionData?.typeAfterCoercion}` : '' + }` + : previewType; const previewContent = !withValidation ? resolvedValue : computeCoersionPreview(resolvedValue, coersionData); @@ -341,6 +351,8 @@ const PreviewCodeBlock = ({ code, isExpectValue = false }) => { if (showJSONTree) { const darkMode = localStorage.getItem('darkMode') === 'true'; + const hasDeepChild = hasDeepChildren(prettyPrintedJson); + return (
{ enableClipboard={false} rootName={false} theme={darkMode ? 'dark' : 'light'} - groupArraysAfterLength={500} + groupArraysAfterLength={hasDeepChild ? 10 : 100} />
); diff --git a/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx b/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx index fad2684660..80f5044c5a 100644 --- a/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx +++ b/frontend/src/Editor/CodeEditor/SingleLineCodeEditor.jsx @@ -193,6 +193,7 @@ const EditorInput = ({ class: 'cm-completionInfo-top cm-custom-completion-info', }; }, + maxRenderedOptions: 10, }); const customKeyMaps = [...defaultKeymap, ...completionKeymap]; diff --git a/frontend/src/Editor/CodeEditor/utils.js b/frontend/src/Editor/CodeEditor/utils.js index 24a9bf5b5e..eb4b57c7ca 100644 --- a/frontend/src/Editor/CodeEditor/utils.js +++ b/frontend/src/Editor/CodeEditor/utils.js @@ -101,26 +101,25 @@ const resolveWorkspaceVariables = (query) => { let resolvedStr = query; let error = null; let valid = false; + // Resolve %%object%% const serverRegex = /(%%.+?%%)/g; - const serverMatch = resolvedStr.match(serverRegex)?.[0]; + const serverMatches = resolvedStr.match(serverRegex); - if (serverMatch) { - const code = serverMatch.replace(/%%/g, ''); + if (serverMatches) { + serverMatches.forEach((serverMatch) => { + const code = serverMatch.replace(/%%/g, ''); - if (code.includes('server.')) { - resolvedStr = resolvedStr.replace(serverMatch, 'HiddenEnvironmentVariable'); - error = 'Server variables cannot be resolved in the client.'; - } else { - const [resolvedCode, err] = resolveCode(code); - - if (!resolvedCode) { - error = err ? err : `Cannot resolve ${query}`; + if (code.includes('server.') && !/^server\.[A-Za-z0-9]+$/.test(code)) { + resolvedStr = resolvedStr.replace(serverMatch, 'HiddenEnvironmentVariable'); } else { + const resolvedCode = resolveCode(code); + resolvedStr = resolvedStr.replace(serverMatch, resolvedCode); - valid = true; } - } + }); + + valid = true; } return [valid, error, resolvedStr]; @@ -407,3 +406,19 @@ export const validateComponentProperty = (resolvedValue, validation) => { return validate(resolvedValue, schema, defaultValue, true); }; + +export function hasDeepChildren(obj, currentDepth = 1, maxDepth = 3) { + if (currentDepth > maxDepth) { + return true; + } + + for (const key in obj) { + if (typeof obj[key] === 'object' && obj[key] !== null) { + if (hasDeepChildren(obj[key], currentDepth + 1, maxDepth)) { + return true; + } + } + } + + return false; +} diff --git a/frontend/src/Editor/Components/Table/Datepicker.jsx b/frontend/src/Editor/Components/Table/Datepicker.jsx index 040fdb8df5..b3b5cc9cc8 100644 --- a/frontend/src/Editor/Components/Table/Datepicker.jsx +++ b/frontend/src/Editor/Components/Table/Datepicker.jsx @@ -206,7 +206,7 @@ export const Datepicker = function Datepicker({ selected={date} onChange={(date) => handleDateChange(date)} value={computeDateString(date)} - dateFormat={dateDisplayFormat} + dateFormat={!isDateSelectionEnabled && isTimeChecked ? 'HH:mm' : dateDisplayFormat} customInput={ } diff --git a/frontend/src/Editor/Components/Table/Link.jsx b/frontend/src/Editor/Components/Table/Link.jsx index 0c05ac0800..fac7129917 100644 --- a/frontend/src/Editor/Components/Table/Link.jsx +++ b/frontend/src/Editor/Components/Table/Link.jsx @@ -19,7 +19,7 @@ export const Link = ({ cellValue, linkTarget, underline, underlineColor, linkCol }} rel="noreferrer" > - {displayText ? displayText : cellValue} + {displayText ? displayText : String(cellValue)}
); diff --git a/frontend/src/Editor/Components/Table/String.jsx b/frontend/src/Editor/Components/Table/String.jsx index 95226ef938..95d24bbd1c 100644 --- a/frontend/src/Editor/Components/Table/String.jsx +++ b/frontend/src/Editor/Components/Table/String.jsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { validateWidget, determineJustifyContentValue } from '@/_helpers/utils'; import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; -const String = ({ +const StringColumn = ({ isEditable, darkMode, handleCellValueChange, @@ -93,7 +93,7 @@ const String = ({ e.stopPropagation(); }} > - {cellValue} + {String(cellValue)}
); @@ -110,7 +110,7 @@ const String = ({ width: `${containerWidth}px`, }} > - {cellValue} + {String(cellValue)}
); @@ -120,7 +120,6 @@ const String = ({ ref?.current && (ref?.current?.clientWidth < ref?.current?.children[0]?.offsetWidth || ref?.current?.clientHeight < ref?.current?.children[0]?.offsetHeight); - return ( <> - {cellValue} + {String(cellValue)}
) : ( @@ -177,4 +176,4 @@ const String = ({ ); }; -export default String; +export default StringColumn; diff --git a/frontend/src/Editor/Components/Table/Tags.jsx b/frontend/src/Editor/Components/Table/Tags.jsx index dc13e4c9d9..1050570826 100644 --- a/frontend/src/Editor/Components/Table/Tags.jsx +++ b/frontend/src/Editor/Components/Table/Tags.jsx @@ -4,7 +4,6 @@ import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; export const Tags = ({ value, onChange, readOnly, containerWidth = '' }) => { const [showOverlay, setShowOverlay] = useState(false); const [hovered, setHovered] = useState(false); - const elem = document.querySelector('.table-tags-col-container'); useEffect(() => { @@ -45,7 +44,7 @@ export const Tags = ({ value, onChange, readOnly, containerWidth = '' }) => { function renderTag(text) { return ( - {text} + {String(text)} {!readOnly && ( removeTag(text)}> x diff --git a/frontend/src/Editor/Components/Table/Text.jsx b/frontend/src/Editor/Components/Table/Text.jsx index 8ead00ab0a..8790772b50 100644 --- a/frontend/src/Editor/Components/Table/Text.jsx +++ b/frontend/src/Editor/Components/Table/Text.jsx @@ -115,7 +115,7 @@ const Text = ({ }} ref={nonEditableCellValueRef} > - {cellValue} + {String(cellValue)}
); diff --git a/frontend/src/Editor/Components/Table/columns/index.jsx b/frontend/src/Editor/Components/Table/columns/index.jsx index 172f23604e..40526d3b97 100644 --- a/frontend/src/Editor/Components/Table/columns/index.jsx +++ b/frontend/src/Editor/Components/Table/columns/index.jsx @@ -13,7 +13,7 @@ import { Boolean } from '../Boolean'; import { CustomSelect } from '../CustomSelect'; import SolidIcon from '@/_ui/Icon/SolidIcons'; import Text from '../Text'; -import String from '../String'; +import StringColumn from '../String'; export default function generateColumnsData({ columnProperties, @@ -152,7 +152,7 @@ export default function generateColumnsData({ case 'default': { const cellTextColor = resolveReferences(column.textColor, currentState, '', { cellValue, rowData }); return ( - - {cellValue} + {String(cellValue)} ); } diff --git a/frontend/src/Editor/Container.jsx b/frontend/src/Editor/Container.jsx index ff979ca18c..d45f06b37f 100644 --- a/frontend/src/Editor/Container.jsx +++ b/frontend/src/Editor/Container.jsx @@ -1070,6 +1070,7 @@ const WidgetWrapper = ({ widgetid={id} style={{ transform: `translate(332px, -134px)`, + zIndex: mode === 'view' && widget.component.component == 'Datepicker' ? 2 : null, ...styles, }} > diff --git a/frontend/src/Editor/Editor.jsx b/frontend/src/Editor/Editor.jsx index ec46785fce..8b858f50fc 100644 --- a/frontend/src/Editor/Editor.jsx +++ b/frontend/src/Editor/Editor.jsx @@ -359,6 +359,19 @@ const EditorComponent = (props) => { () => { const components = appDefinition?.pages?.[currentPageId]?.components || {}; computeComponentState(components); + + const isPageSwitched = useResolveStore.getState().isPageSwitched; + + if (isPageSwitched) { + const currentStateObj = useCurrentStateStore.getState(); + + useResolveStore.getState().actions.addAppSuggestions({ + queries: currentStateObj.queries, + components: currentStateObj.components, + page: currentStateObj.page, + }); + useResolveStore.getState().actions.pageSwitched(false); + } }, // eslint-disable-next-line react-hooks/exhaustive-deps [currentPageId] @@ -744,7 +757,7 @@ const EditorComponent = (props) => { user_id: userId, events, } = appData; - useResolveStore.getState().actions.updateJSHints(); + const startingPageHandle = props.params.pageHandle; setWindowTitle({ page: pageTitles.EDITOR, appName }); useAppVersionStore.getState().actions.updateEditingVersion(editing_version); @@ -765,7 +778,7 @@ const EditorComponent = (props) => { await processNewAppDefinition(appData, startingPageHandle, false, ({ homePageId }) => { handleLowPriorityWork(async () => { - useResolveStore.getState().actions.updateLastUpdatedRefs(['constants']); + useResolveStore.getState().actions.updateLastUpdatedRefs(['constants', 'client']); await useDataSourcesStore.getState().actions.fetchGlobalDataSources(organizationId); await fetchDataSources(editing_version?.id); commonLowPriorityActions(events, { homePageId }); @@ -781,6 +794,7 @@ const EditorComponent = (props) => { }; const processNewAppDefinition = async (data, startingPageHandle, versionSwitched = false, onComplete) => { + useResolveStore.getState().actions.updateJSHints(); const appDefData = buildAppDefinition(data); const appJson = appDefData; @@ -1440,6 +1454,7 @@ const EditorComponent = (props) => { useCurrentStateStore.getState().actions.setEditorReady(true); const currentComponents = appJson?.pages?.[pageId]?.components; + const currentDataQueries = useDataQueriesStore.getState().dataQueries; const referenceManager = useResolveStore.getState().referenceMapper; @@ -1453,8 +1468,17 @@ const EditorComponent = (props) => { }; } }); + const newDataQueries = currentDataQueries.map((dq) => { + if (!referenceManager.get(dq.id)) { + return { + id: dq.id, + name: dq.name, + }; + } + }); - useResolveStore.getState().actions.addEntitiesToMap(newComponents); + useResolveStore.getState().actions.addEntitiesToMap([...newComponents, ...newDataQueries]); + // useResolveStore.getState().actions.addEntitiesToMap(newDataQueries); }; const updateEntityReferences = (appJson, pageId) => { @@ -1675,11 +1699,11 @@ const EditorComponent = (props) => { switchPage: true, pageId: newPageId, }); - props?.navigate(`/${getWorkspaceId()}/apps/${slug ?? appId}/${newHandle}`, { - state: { - isSwitchingPage: true, - }, - }); + // props?.navigate(`/${getWorkspaceId()}/apps/${slug ?? appId}/${newHandle}`, { + // state: { + // isSwitchingPage: true, + // }, + // }); const page = { id: newPageId, @@ -1714,14 +1738,15 @@ const EditorComponent = (props) => { return; } - clearAllQueuedTasks(); + await clearAllQueuedTasks(); + useResolveStore.getState().actions.resetStore(); useEditorStore.getState().actions.setPageProgress(true); useCurrentStateStore.getState().actions.setEditorReady(false); - useResolveStore.getState().actions.resetStore(); // This are fetched from store to handle runQueriesOnAppLoad const currentPageId = useEditorStore.getState().currentPageId; const appDefinition = useEditorStore.getState().appDefinition; - const pageHandle = getCurrentState().pageHandle; + + const pageHandle = useCurrentStateStore.getState().page?.handle; if (currentPageId === pageId && pageHandle === appDefinition?.pages[pageId]?.handle) { return; @@ -1730,6 +1755,7 @@ const EditorComponent = (props) => { if (!name || !handle) return; const copyOfAppDefinition = JSON.parse(JSON.stringify(appDefinition)); + navigateToPage(queryParams, handle); const page = { @@ -1750,9 +1776,6 @@ const EditorComponent = (props) => { await onEditorLoad(appDefinition, pageId, true); updateEntityReferences(appDefinition, pageId); - handleLowPriorityWork(() => { - useResolveStore.getState().actions.updateJSHints(); - }); setCurrentPageId(pageId); @@ -1761,9 +1784,14 @@ const EditorComponent = (props) => { .events.filter((event) => event.target === 'page' && event.sourceId === page.id); handleEvent('onPageLoad', currentPageEvents); - handleLowPriorityWork(() => { - useEditorStore.getState().actions.setPageProgress(false); - }, 100); + handleLowPriorityWork( + () => { + useEditorStore.getState().actions.setPageProgress(false); + useResolveStore.getState().actions.updateJSHints(); + }, + null, + true + ); }; const deletePageRequest = (pageId, isHomePage = false, pageName = '') => { diff --git a/frontend/src/Editor/Viewer.jsx b/frontend/src/Editor/Viewer.jsx index fdba792bd0..041fc16532 100644 --- a/frontend/src/Editor/Viewer.jsx +++ b/frontend/src/Editor/Viewer.jsx @@ -323,12 +323,14 @@ class ViewerComponent extends React.Component { queryState[query.name] = { ...exposedVariables, ...this.props.currentState.queries[query.name], + id: query.id, }; } else { const dataSourceTypeDetail = DataSourceTypes.find((source) => source.kind === query.kind); queryState[query.name] = { ...dataSourceTypeDetail.exposedVariables, ...this.props.currentState.queries[query.name], + id: query.id, }; } }); @@ -736,7 +738,7 @@ class ViewerComponent extends React.Component { if (currentPageComponents && !_.isEmpty(currentPageComponents)) { const referenceManager = useResolveStore.getState().referenceMapper; - + const currentDataQueries = useDataQueriesStore.getState().dataQueries; const newComponents = Object.keys(currentPageComponents).map((componentId) => { const component = currentPageComponents[componentId]; @@ -747,9 +749,18 @@ class ViewerComponent extends React.Component { }; } }); + const newDataQueries = currentDataQueries.map((dq) => { + if (!referenceManager.get(dq.id)) { + return { + id: dq.id, + name: dq.name, + }; + } + }); try { useResolveStore.getState().actions.addEntitiesToMap(newComponents); + useResolveStore.getState().actions.addEntitiesToMap(newDataQueries); } catch (error) { console.error(error); } @@ -1043,6 +1054,18 @@ const withStore = (Component) => (props) => { flushComponentsToRender(updatedComponentIds); } + React.useEffect(() => { + const currentComponentsDef = appDefinition?.pages?.[currentPageId]?.components || {}; + const currentComponents = Object.keys(currentComponentsDef); + + setTimeout(() => { + if (currentComponents.length > 0) { + batchUpdateComponents(currentComponents); + } + }, 400); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPageId]); + React.useEffect(() => { if (lastUpdatedRef.length > 0) { const currentComponents = appDefinition?.pages?.[currentPageId]?.components || {}; diff --git a/frontend/src/_helpers/editorHelpers.js b/frontend/src/_helpers/editorHelpers.js index 342f26b1fc..71988fcc74 100644 --- a/frontend/src/_helpers/editorHelpers.js +++ b/frontend/src/_helpers/editorHelpers.js @@ -146,7 +146,10 @@ function findReferenceInComponent(node, changedCurrentState) { if (typeof node === 'object') { for (let key in node) { const value = node[key]; - if (typeof value === 'string' && value.includes('{{') && value.includes('}}')) { + if ( + typeof value === 'string' && + ((value.includes('{{') && value.includes('}}')) || value.includes('%%client')) + ) { // Check if the referenced entity is in the state if (changedCurrentState.some((state) => value.includes(state))) { return true; diff --git a/frontend/src/_stores/currentStateStore.js b/frontend/src/_stores/currentStateStore.js index e2e16b123d..3f4d746312 100644 --- a/frontend/src/_stores/currentStateStore.js +++ b/frontend/src/_stores/currentStateStore.js @@ -105,7 +105,7 @@ useCurrentStateStore.subscribe((state) => { () => { useResolveStore.getState().actions.updateAppSuggestions({ queries: state.queries, - components: state.components, + components: !isPageSwitched ? state.components : {}, globals: state.globals, page: state.page, variables: state.variables, @@ -113,7 +113,6 @@ useCurrentStateStore.subscribe((state) => { server: state.server, constants: state.constants, }); - useResolveStore.getState().actions.pageSwitched(false); }, null, isPageSwitched diff --git a/frontend/src/_stores/resolverStore.js b/frontend/src/_stores/resolverStore.js index 14f84c615e..5deb238ac9 100644 --- a/frontend/src/_stores/resolverStore.js +++ b/frontend/src/_stores/resolverStore.js @@ -71,7 +71,7 @@ export const useResolveStore = create( set(() => ({ ...state, storeReady: true })); }, resetStore: () => { - set(() => initialState); + set(() => ({ ...initialState, referenceMapper: new ReferencesBiMap() })); }, pageSwitched: (bool) => set(() => ({ isPageSwitched: bool })), updateAppSuggestions: (refState) => { diff --git a/server/.version b/server/.version index 57c32dea2e..ed23763f45 100644 --- a/server/.version +++ b/server/.version @@ -1 +1 @@ -2.50.3 +2.50.4