Merge branch 'feat/grid-appbuilder-improvement' into builder-performance-platform-part/release

This commit is contained in:
Muhsin Shah 2024-04-12 15:14:27 +05:30
commit 647e537254
7 changed files with 212 additions and 158 deletions

View file

@ -130,7 +130,7 @@ const EditorInput = ({
if (totalReferences > 1) {
const currentWord = queryInput.split('{{').pop().split('}}')[0];
queryInput = currentWord;
queryInput = '{{' + currentWord + '}}';
}
let completions = getAutocompletion(queryInput, validationType, hints, totalReferences);

View file

@ -67,7 +67,7 @@ export const generateHints = (hints, totalReferences = 1) => {
if (!hints) return [];
const suggestions = hints.map(({ hint, type }) => {
let displayedHint = type === 'js_method' ? `${hint}()` : hint;
let displayedHint = type === 'js_method' || type === 'Function' ? `${hint}()` : hint;
const maxHintLength = 20;
const hintLength = displayedHint.length;

View file

@ -224,7 +224,7 @@ export const TextInput = function TextInput({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [disable]);
const renderInput = () => (
return (
<>
<div
data-cy={`label-${String(component.name).toLowerCase()}`}
@ -235,8 +235,8 @@ export const TextInput = function TextInput({
? 'flex-column'
: 'align-items-center '
} ${direction === 'right' && defaultAlignment === 'side' ? 'flex-row-reverse' : ''}
${direction === 'right' && defaultAlignment === 'top' ? 'text-right' : ''}
${visibility || 'invisible'}`}
${direction === 'right' && defaultAlignment === 'top' ? 'text-right' : ''}
${visibility || 'invisible'}`}
style={{
position: 'relative',
whiteSpace: 'nowrap',
@ -339,6 +339,4 @@ export const TextInput = function TextInput({
)}
</>
);
return <>{renderInput()}</>;
};

View file

@ -13,7 +13,6 @@ import config from 'config';
import Spinner from '@/_ui/Spinner';
import { useHotkeys } from 'react-hotkeys-hook';
import { addComponents, addNewWidgetToTheEditor, isPDFSupported } from '@/_helpers/appUtils';
import { useCurrentState } from '@/_stores/currentStateStore';
import { useAppVersionStore } from '@/_stores/appVersionStore';
import { useEditorStore } from '@/_stores/editorStore';
import { useAppInfo } from '@/_stores/appDataStore';
@ -31,7 +30,7 @@ import { useDraggedSubContainer, useGridStore } from '@/_stores/gridStore';
const deviceWindowWidth = EditorConstants.deviceWindowWidth;
export const Container = ({
canvasWidth,
widthOfCanvas,
mode,
snapToGrid,
onComponentClick,
@ -72,10 +71,13 @@ export const Container = ({
shallow
);
const canvasWidth = widthOfCanvas
? widthOfCanvas
: document.getElementsByClassName('canvas-area')[0]?.getBoundingClientRect()?.width;
const gridWidth = canvasWidth / noOfGrids;
const { appId } = useAppInfo();
const currentState = useCurrentState();
const { appVersionsId, isVersionReleased } = useAppVersionStore(
(state) => ({
appVersionsId: state?.editingVersion?.id,
@ -189,7 +191,7 @@ export const Container = ({
} else {
const diffState = diff(components, boxes);
if (!_.isEmpty(diffState) && !isOnlyLayoutUpdate(diffState)) {
if (!_.isEmpty(diffState)) {
setBoxes(components);
}
}
@ -244,6 +246,8 @@ export const Container = ({
return;
}
if (!appDefinition.pages[currentPageId]?.components) return;
const newDefinition = {
...appDefinition,
pages: {
@ -251,7 +255,7 @@ export const Container = ({
[currentPageId]: {
...appDefinition.pages[currentPageId],
components: {
...appDefinition.pages[currentPageId].components,
...appDefinition.pages[currentPageId]?.components,
...boxes,
},
},
@ -594,23 +598,21 @@ export const Container = ({
...updatedBoxes,
};
handleLowPriorityWork(() => {
const diffState = diff(boxes, newBoxes);
const diffState = diff(boxes, newBoxes);
setBoxes((prev) => {
const updatedComponentsAsperDiff = Object.keys(diffState).reduce((acc, key) => {
const component = newBoxes[key];
if (component) {
acc[key] = component;
}
return acc;
}, {});
setBoxes((prev) => {
const updatedComponentsAsperDiff = Object.keys(diffState).reduce((acc, key) => {
const component = newBoxes[key];
if (component) {
acc[key] = component;
}
return acc;
}, {});
return {
...prev,
...updatedComponentsAsperDiff,
};
});
return {
...prev,
...updatedComponentsAsperDiff,
};
});
updateCanvasHeight(newBoxes);
@ -762,7 +764,6 @@ export const Container = ({
onEvent,
appDefinition,
appDefinitionChanged,
currentState,
appLoading,
zoomLevel,
setSelectedComponent,

View file

@ -59,7 +59,7 @@ import { useDataSourcesStore } from '@/_stores/dataSourcesStore';
import { useDataQueriesStore } from '@/_stores/dataQueriesStore';
import { useAppVersionStore, useAppVersionActions } from '@/_stores/appVersionStore';
import { useQueryPanelStore } from '@/_stores/queryPanelStore';
import { useCurrentStateStore, useCurrentState, getCurrentState } from '@/_stores/currentStateStore';
import { useCurrentStateStore, getCurrentState } from '@/_stores/currentStateStore';
import {
computeAppDiff,
computeComponentPropertyDiff,
@ -184,8 +184,6 @@ const EditorComponent = (props) => {
shallow
);
const currentState = useCurrentState();
const [zoomLevel, setZoomLevel] = useState(1);
const [isQueryPaneDragging, setIsQueryPaneDragging] = useState(false);
const [isQueryPaneExpanded, setIsQueryPaneExpanded] = useState(false); //!check where this is used
@ -241,7 +239,7 @@ const EditorComponent = (props) => {
});
useCurrentStateStore.getState().actions.setCurrentState({
globals: {
...currentState.globals,
...getCurrentState().globals,
theme: { name: props?.darkMode ? 'dark' : 'light' },
urlparams: JSON.parse(JSON.stringify(queryString.parse(props.location.search))),
currentUser: userVars,
@ -621,7 +619,7 @@ const EditorComponent = (props) => {
const changeDarkMode = (newMode) => {
useCurrentStateStore.getState().actions.setCurrentState({
globals: {
...currentState.globals,
...getCurrentState().globals,
theme: { name: newMode ? 'dark' : 'light' },
},
});
@ -1288,7 +1286,9 @@ const EditorComponent = (props) => {
const _appDefinition = JSON.parse(JSON.stringify(appDefinition));
let newComponents = _appDefinition?.pages[currentPageId].components;
const selectedComponents = useEditorStore.getState()?.selectedComponents;
const componentsIds = [];
for (const selectedComponent of selectedComponents) {
componentsIds.push(selectedComponent.id);
let top = newComponents[selectedComponent.id].layouts[currentLayout].top;
let left = newComponents[selectedComponent.id].layouts[currentLayout].left;
const width = newComponents[selectedComponent.id]?.layouts[currentLayout]?.width;
@ -1325,6 +1325,8 @@ const EditorComponent = (props) => {
_appDefinition.pages[currentPageId].components = newComponents;
appDefinitionChanged(_appDefinition, { containerChanges: true, widgetMovedWithKeyboard: true });
// console.log('arpit::', { componentsIds });
// updateComponentsNeedsUpdateOnNextRender(componentsIds);
};
const copyComponents = () =>
@ -1612,7 +1614,7 @@ const EditorComponent = (props) => {
};
const globals = {
...currentState.globals,
...getCurrentState().globals,
};
useCurrentStateStore.getState().actions.setCurrentState({ globals, page });
};
@ -1654,7 +1656,7 @@ const EditorComponent = (props) => {
const queryParamsString = queryParams.map(([key, value]) => `${key}=${value}`).join('&');
const globals = {
...currentState.globals,
...getCurrentState().globals,
urlparams: JSON.parse(JSON.stringify(queryString.parse(queryParamsString))),
};
@ -2092,7 +2094,7 @@ const EditorComponent = (props) => {
{defaultComponentStateComputed && (
<>
<Container
canvasWidth={getCanvasWidth()}
widthOfCanvas={getCanvasWidth()}
socket={socket}
appDefinitionChanged={appDefinitionChanged}
snapToGrid={true}

View file

@ -50,8 +50,6 @@ import { useResolveStore } from '@/_stores/resolverStore';
import { findComponentsWithReferences } from '@/_helpers/editorHelpers';
import { findAllEntityReferences } from '@/_stores/utils';
import { dfs } from '@/_stores/handleReferenceTransactions';
// eslint-disable-next-line import/no-unresolved
import produce from 'immer';
class ViewerComponent extends React.Component {
constructor(props) {
@ -104,7 +102,125 @@ class ViewerComponent extends React.Component {
});
useEditorStore.getState().actions.updateEditorState({
appDefinition: { ...appDefData },
appDefinition: appDefData,
});
};
onViewerLoadUpdateEntityReferences = (pageId, loadType) => {
const appDefData = useEditorStore.getState().appDefinition;
const appJson = JSON.parse(JSON.stringify(appDefData));
const currentPageId = pageId ?? this.state.currentPageId;
const currentComponents = appJson.pages[currentPageId].components;
let dataQueries = JSON.parse(JSON.stringify(useDataQueriesStore.getState().dataQueries));
let allEvents = JSON.parse(JSON.stringify(useAppDataStore.getState().events));
const entityReferencesInComponentDefinitions = findAllEntityReferences(currentComponents, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const entityReferencesInQueryOptions = findAllEntityReferences(dataQueries, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const entityReferencesInEvents = findAllEntityReferences(allEvents, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const manager = useResolveStore.getState().referenceMapper;
if (Array.isArray(entityReferencesInComponentDefinitions) && entityReferencesInComponentDefinitions?.length > 0) {
let newComponentDefinition = JSON.parse(JSON.stringify(currentComponents));
entityReferencesInComponentDefinitions.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newComponentDefinition = dfs(newComponentDefinition, entity, value);
}
});
const newAppDefinition = {
...appJson,
pages: {
...appJson.pages,
[currentPageId]: {
...appJson.pages[currentPageId],
components: newComponentDefinition,
},
},
};
useEditorStore.getState().actions.updateEditorState({
isUpdatingEditorStateInProcess: false,
appDefinition: newAppDefinition,
});
this.setState({
appDefinition: newAppDefinition,
});
}
if (Array.isArray(entityReferencesInQueryOptions) && entityReferencesInQueryOptions?.length > 0) {
let newQueryOptions = {};
dataQueries?.forEach((query) => {
newQueryOptions[query.id] = query.options;
``;
});
entityReferencesInQueryOptions.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newQueryOptions = dfs(newQueryOptions, entity, value);
}
});
dataQueries = dataQueries.map((query) => {
const queryId = query.id;
const dqOptions = newQueryOptions[queryId];
return {
...query,
options: dqOptions,
};
});
useDataQueriesStore.getState().actions.setDataQueries(dataQueries, 'mappingUpdate');
}
if (Array.isArray(entityReferencesInEvents) && entityReferencesInEvents?.length > 0) {
let newEvents = JSON.parse(JSON.stringify(allEvents));
entityReferencesInEvents.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newEvents = dfs(newEvents, entity, value);
}
});
this.props.updateState({
events: newEvents,
});
}
computeComponentState(currentComponents).then(async () => {
this.setState({ initialComputationOfStateDone: true, defaultComponentStateComputed: true });
useCurrentStateStore.getState().actions.setEditorReady(true);
if (loadType === 'appload') {
this.runQueries(dataQueries);
}
const currentPageEvents = this.state.events.filter(
(event) => event.target === 'page' && event.sourceId === this.state.currentPageId
);
await this.handleEvent('onPageLoad', currentPageEvents);
});
};
@ -198,7 +314,7 @@ class ViewerComponent extends React.Component {
});
useEditorStore.getState().actions.toggleCurrentLayout(this.props?.currentLayout == 'mobile' ? 'mobile' : 'desktop');
this.props.updateState({ events: data.events ?? [] });
const currentPageComponents = appDefData?.pages[currentPageId]?.components;
const currentPageComponents = appDefData?.pages[currentPage.id]?.components;
if (currentPageComponents && !_.isEmpty(currentPageComponents)) {
const referenceManager = useResolveStore.getState().referenceMapper;
@ -234,110 +350,7 @@ class ViewerComponent extends React.Component {
events: data.events ?? [],
},
() => {
// const components = appDefData?.pages[currentPageId]?.components || {};
const appJson = JSON.parse(JSON.stringify(appDefData));
const currentPageId = useEditorStore.getState().currentPageId;
const currentComponents = useEditorStore.getState().appDefinition?.pages?.[currentPageId]?.components;
let dataQueries = JSON.parse(JSON.stringify(useDataQueriesStore.getState().dataQueries));
let allEvents = JSON.parse(JSON.stringify(useAppDataStore.getState().events));
const entityReferencesInComponentDefinitions = findAllEntityReferences(currentComponents, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const entityReferencesInQueryOptions = findAllEntityReferences(dataQueries, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const entityReferencesInEvents = findAllEntityReferences(allEvents, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const manager = useResolveStore.getState().referenceMapper;
if (
Array.isArray(entityReferencesInComponentDefinitions) &&
entityReferencesInComponentDefinitions?.length > 0
) {
let newComponentDefinition = JSON.parse(JSON.stringify(currentComponents));
entityReferencesInComponentDefinitions.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newComponentDefinition = dfs(newComponentDefinition, entity, value);
}
});
const newAppDefinition = produce(appJson, (draft) => {
draft.pages[homePageId].components = newComponentDefinition;
});
useEditorStore.getState().actions.updateEditorState({
isUpdatingEditorStateInProcess: false,
appDefinition: newAppDefinition,
});
}
if (Array.isArray(entityReferencesInQueryOptions) && entityReferencesInQueryOptions?.length > 0) {
let newQueryOptions = {};
dataQueries?.forEach((query) => {
newQueryOptions[query.id] = query.options;
``;
});
entityReferencesInQueryOptions.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newQueryOptions = dfs(newQueryOptions, entity, value);
}
});
dataQueries = dataQueries.map((query) => {
const queryId = query.id;
const dqOptions = newQueryOptions[queryId];
return {
...query,
options: dqOptions,
};
});
useDataQueriesStore.getState().actions.setDataQueries(dataQueries, 'mappingUpdate');
}
if (Array.isArray(entityReferencesInEvents) && entityReferencesInEvents?.length > 0) {
let newEvents = JSON.parse(JSON.stringify(allEvents));
entityReferencesInEvents.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newEvents = dfs(newEvents, entity, value);
}
});
this.props.updateState({
events: newEvents,
});
}
computeComponentState(currentComponents).then(async () => {
this.setState({ initialComputationOfStateDone: true, defaultComponentStateComputed: true });
useCurrentStateStore.getState().actions.setEditorReady(true);
this.runQueries(dataQueries);
const currentPageEvents = this.state.events.filter(
(event) => event.target === 'page' && event.sourceId === this.state.currentPageId
);
await this.handleEvent('onPageLoad', currentPageEvents);
});
this.onViewerLoadUpdateEntityReferences(currentPage.id, 'appload');
}
);
};
@ -637,6 +650,8 @@ class ViewerComponent extends React.Component {
const defaultParams = getPreviewQueryParams();
if (this.state.currentPageId === id) return;
useCurrentStateStore.getState().actions.setEditorReady(false);
useResolveStore.getState().actions.resetStore();
const { handle } = this.state.appDefinition.pages[id];
@ -654,20 +669,58 @@ class ViewerComponent extends React.Component {
? `version=${navigationParams.version}`
: '';
this.props.navigate(
`/applications/${this.state.slug}/${handle}?${!_.isEmpty(defaultParams) ? navigationParamsString : ''}${
queryParamsString ? `${!_.isEmpty(defaultParams) ? '&' : ''}${queryParamsString}` : ''
}`,
{
state: {
isSwitchingPage: true,
},
useEditorStore.getState().actions.updateEditorState({
currentPageId: id,
});
const currentPageComponents = this.state.appDefinition?.pages[id]?.components;
if (currentPageComponents && !_.isEmpty(currentPageComponents)) {
const referenceManager = useResolveStore.getState().referenceMapper;
const newComponents = Object.keys(currentPageComponents).map((componentId) => {
const component = currentPageComponents[componentId];
if (!referenceManager.get(componentId)) {
return {
id: componentId,
name: component.component.name,
};
}
});
try {
useResolveStore.getState().actions.addEntitiesToMap(newComponents);
} catch (error) {
console.error(error);
}
);
}
const toNavigate = `/applications/${this.state.slug}/${handle}?${
!_.isEmpty(defaultParams) ? navigationParamsString : ''
}${queryParamsString ? `${!_.isEmpty(defaultParams) ? '&' : ''}${queryParamsString}` : ''}`;
this.props.navigate(toNavigate, {
state: {
isSwitchingPage: true,
},
});
this.onViewerLoadUpdateEntityReferences(id, 'page-switch');
};
handleEvent = (eventName, events, options) => {
return onEvent(this.getViewerRef(), eventName, events, options, 'view');
const latestEvents = useAppDataStore.getState().events;
const filteredEvents = latestEvents.filter((event) => {
const foundEvent = events.find((e) => e.id === event.id);
return foundEvent && foundEvent.name === eventName;
});
try {
return onEvent(this.getViewerRef(), eventName, filteredEvents, options, 'view');
} catch (error) {
console.error(error);
}
};
computeCanvasMaxWidth = () => {
@ -890,11 +943,12 @@ class ViewerComponent extends React.Component {
}
const withStore = (Component) => (props) => {
const currentState = useCurrentStateStore();
const { currentLayout, queryConfirmationList, currentPageId } = useEditorStore(
const { currentLayout, queryConfirmationList, currentPageId, appDefinition } = useEditorStore(
(state) => ({
currentLayout: state?.currentLayout,
queryConfirmationList: state?.queryConfirmationList,
currentPageId: state?.currentPageId,
appDefinition: state?.appDefinition,
}),
shallow
);
@ -920,13 +974,12 @@ const withStore = (Component) => (props) => {
await new Promise((resolve) => setTimeout(resolve, 0));
}
// Flush only updated components
flushComponentsToRender(updatedComponentIds);
}
React.useEffect(() => {
if (lastUpdatedRef.length > 0) {
const currentComponents = useEditorStore.getState().appDefinition?.pages?.[currentPageId]?.components || {};
const currentComponents = appDefinition?.pages?.[currentPageId]?.components || {};
const componentIdsWithReferences = findComponentsWithReferences(currentComponents, lastUpdatedRef);
if (componentIdsWithReferences.length > 0) {

View file

@ -118,5 +118,5 @@ export const flushComponentsToRender = (componentIds = []) => {
if (!componentIds.length) return;
useEditorStore.getState().actions.flushComponentsNeedsUpdateOnNextRender(componentIds);
useResolveStore.getState().actions.getLastUpdatedRefs();
useResolveStore.getState().actions.flushLastUpdatedRefs();
};