Revert "Merge branch 'feat/grid-appbuilder-improvement' into core-performance/appbuilder"

This reverts commit 2e8374ac31, reversing
changes made to 23a86bfe6e.
This commit is contained in:
arpitnath 2024-04-03 04:11:06 +05:30
parent 2e8374ac31
commit 858dff3606
8 changed files with 111 additions and 358 deletions

View file

@ -793,17 +793,29 @@ const EditorComponent = (props) => {
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 entityReferencesInComponentDefinitions = findAllEntityReferences(currentComponents, [])
?.map((entity) => {
if (entity && isValidUUID(entity)) {
return entity;
}
})
?.filter((e) => e !== undefined);
const entityReferencesInQueryoOptions = findAllEntityReferences(dataQueries, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const entityReferencesInQueryoOptions = findAllEntityReferences(dataQueries, [])
?.map((entity) => {
if (entity && isValidUUID(entity)) {
return entity;
}
})
?.filter((e) => e !== undefined);
const entityReferencesInEvents = findAllEntityReferences(allEvents, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const entityReferencesInEvents = findAllEntityReferences(allEvents, [])
?.map((entity) => {
if (entity && isValidUUID(entity)) {
return entity;
}
})
?.filter((e) => e !== undefined);
const manager = useResolveStore.getState().referenceMapper;
@ -1343,7 +1355,6 @@ const EditorComponent = (props) => {
});
delete newDefinition.pages[currentPageId].components[componentId];
const platform = navigator?.userAgentData?.platform || navigator?.platform || 'unknown';
if (platform.toLowerCase().indexOf('mac') > -1) {
toast('Component deleted! (⌘ + Z to undo)', {
@ -1378,31 +1389,6 @@ const EditorComponent = (props) => {
});
}
const newAppDefinition = JSON.parse(JSON.stringify(useEditorStore.getState().appDefinition));
const currentComponents = newAppDefinition.pages[currentPageId].components;
const currentDataQueries = useDataQueriesStore.getState().dataQueries;
const newComponentDefinition = useResolveStore
.getState()
.actions.findAndReplaceReferences(currentComponents, deletedComponentNames);
const entityReferencesInQuerries = findAllEntityReferences(currentDataQueries, []);
if (entityReferencesInQuerries.length > 0) {
const newDataQueries = useResolveStore
.getState()
.actions.findAndReplaceReferences(currentDataQueries, deletedComponentNames);
useDataQueriesStore.getState().actions.setDataQueries(newDataQueries, 'mappingUpdate');
}
newAppDefinition.pages[currentPageId].components = newComponentDefinition;
useEditorStore.getState().actions.updateEditorState({
appDefinition: newAppDefinition,
isUpdatingEditorStateInProcess: true,
});
useResolveStore.getState().actions.removeEntitiesFromMap(deleteFromMap);
useResolveStore.getState().actions.removeAppSuggestions(allHintsAssociatedWithQuery);
} else {

View file

@ -4,6 +4,7 @@ import {
authenticationService,
orgEnvironmentVariableService,
orgEnvironmentConstantService,
dataqueryService,
appService,
appEnvironmentService,
} from '@/_services';
@ -20,11 +21,11 @@ import {
runQuery,
computeComponentState,
buildAppDefinition,
runQueries,
} from '@/_helpers/appUtils';
import queryString from 'query-string';
import ViewerLogoIcon from './Icons/viewer-logo.svg';
import { resolveReferences, isQueryRunnable, setWindowTitle, pageTitles, isValidUUID } from '@/_helpers/utils';
import { DataSourceTypes } from './DataSourceManager/SourceComponents';
import { resolveReferences, isQueryRunnable, setWindowTitle, pageTitles } from '@/_helpers/utils';
import { withTranslation } from 'react-i18next';
import _ from 'lodash';
import { Navigate } from 'react-router-dom';
@ -45,10 +46,6 @@ import ViewerSidebarNavigation from './Viewer/ViewerSidebarNavigation';
import MobileHeader from './Viewer/MobileHeader';
import DesktopHeader from './Viewer/DesktopHeader';
import './Viewer/viewer.scss';
import { findAllEntityReferences } from '@/_stores/utils';
import { useResolveStore } from '@/_stores/resolverStore';
import { dfs } from '@/_stores/handleReferenceTransactions';
const { produce } = require('immer');
class ViewerComponent extends React.Component {
constructor(props) {
@ -120,26 +117,41 @@ class ViewerComponent extends React.Component {
let dataQueries = [];
if (appVersionId) {
await useDataQueriesStore.getState().actions.fetchDataQueries(appVersionId, false, true);
const { data_queries } = await dataqueryService.getAll(appVersionId);
dataQueries = data_queries;
} else {
dataQueries = data.data_queries;
}
const queryConfirmationList = [];
const referencesManager = useResolveStore.getState().referenceMapper;
const newQueries = dataQueries
.map((dq) => {
if (!referencesManager.get(dq.id)) {
return {
id: dq.id,
name: dq.name,
};
}
})
.filter((c) => c !== undefined);
if (dataQueries.length > 0) {
dataQueries.forEach((query) => {
if (query?.options && query?.options?.requestConfirmation && query?.options?.runOnPageLoad) {
queryConfirmationList.push({ queryId: query.id, queryName: query.name });
}
useResolveStore.getState().actions.addEntitiesToMap(newQueries);
useDataQueriesStore.getState().actions.setDataQueries(dataQueries);
if (query.pluginId || query?.plugin?.id) {
const exposedVariables =
query.plugin?.manifestFile?.data?.source?.exposedVariables ||
query.plugin?.manifest_file?.data?.source?.exposed_variables;
queryState[query.name] = {
...exposedVariables,
...this.props.currentState.queries[query.name],
};
} else {
const dataSourceTypeDetail = DataSourceTypes.find((source) => source.kind === query.kind);
queryState[query.name] = {
...dataSourceTypeDetail.exposedVariables,
...this.props.currentState.queries[query.name],
};
}
});
}
if (queryConfirmationList.length !== 0) {
this.updateQueryConfirmationList(queryConfirmationList);
}
const variables = await this.fetchOrgEnvironmentVariables(data.slug, data.is_public);
const constants = await this.fetchOrgEnvironmentConstants(data.slug, data.is_public);
@ -149,25 +161,7 @@ class ViewerComponent extends React.Component {
const currentPageId = pages.filter((page) => page.handle === startingPageHandle)[0]?.id ?? homePageId;
const currentPage = pages.find((page) => page.id === currentPageId);
const currentComponents = appDefData?.pages?.[currentPageId]?.components;
if (currentComponents && Object.keys(currentComponents).length > 0) {
const referenceManager = useResolveStore.getState().referenceMapper;
const newComponents = Object.keys(currentComponents).map((componentId) => {
const component = currentComponents[componentId];
if (!referenceManager.get(componentId)) {
return {
id: componentId,
name: component.component.name,
};
}
});
useResolveStore.getState().actions.addEntitiesToMap(newComponents);
}
useDataQueriesStore.getState().actions.setDataQueries(dataQueries);
this.props.setCurrentState({
queries: queryState,
components: {},
@ -191,7 +185,6 @@ class ViewerComponent extends React.Component {
});
useEditorStore.getState().actions.toggleCurrentLayout(this.props?.currentLayout == 'mobile' ? 'mobile' : 'desktop');
this.props.updateState({ events: data.events ?? [] });
this.setState(
{
currentUser,
@ -209,108 +202,18 @@ class ViewerComponent extends React.Component {
events: data.events ?? [],
},
() => {
let components = this.state.appDefinition?.pages[currentPageId]?.components || {};
let allEvents = data.events || [];
let allDataQueries = this.state.dataQueries || [];
let newComponentDefinition = JSON.parse(JSON.stringify(components));
const components = appDefData?.pages[currentPageId]?.components || {};
const entityReferencesInComponentDefinitions = findAllEntityReferences(newComponentDefinition, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
computeComponentState(components).then(async () => {
this.setState({ initialComputationOfStateDone: true, defaultComponentStateComputed: true });
this.runQueries(dataQueries);
const entityReferencesInQueryoOptions = findAllEntityReferences(allDataQueries, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const currentPageEvents = this.state.events.filter(
(event) => event.target === 'page' && event.sourceId === this.state.currentPageId
);
const entityReferencesInEvents = findAllEntityReferences(allEvents, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const manager = useResolveStore.getState().referenceMapper;
if (
Array.isArray(entityReferencesInComponentDefinitions) &&
entityReferencesInComponentDefinitions?.length > 0
) {
entityReferencesInComponentDefinitions.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newComponentDefinition = dfs(newComponentDefinition, entity, value);
}
const newAppDefinition = produce(this.state.appDefinition, (draft) => {
draft.pages[homePageId].components = newComponentDefinition;
});
components = newComponentDefinition;
this.setState({
appDefinition: newAppDefinition,
});
});
if (Array.isArray(entityReferencesInQueryoOptions) && entityReferencesInQueryoOptions?.length > 0) {
let newQueryOptions = {};
allDataQueries?.forEach((query) => {
newQueryOptions[query.id] = query.options;
});
entityReferencesInQueryoOptions.forEach((entity) => {
const entityrefExists = manager.has(entity);
if (entityrefExists) {
const value = manager.get(entity);
newQueryOptions = dfs(newQueryOptions, entity, value);
}
});
allDataQueries = allDataQueries.map((query) => {
const queryId = query.id;
const dqOptions = newQueryOptions[queryId];
return {
...query,
options: dqOptions,
};
});
useDataQueriesStore.getState().actions.setDataQueries(allDataQueries);
}
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(newComponentDefinition)
.then(async () => {
this.setState({ initialComputationOfStateDone: true, defaultComponentStateComputed: true });
const queuedQueriesForRunOnAppLoad = useDataQueriesStore.getState().queuedQueriesForRunOnAppLoad;
const viewerRef = this.getViewerRef();
await runQueries(queuedQueriesForRunOnAppLoad, viewerRef, 'view');
useDataQueriesStore.getState().actions.clearQueuedQueriesForRunOnAppLoad();
})
.finally(async () => {
const currentPageEvents = data.events.filter(
(event) => event.target === 'page' && event.sourceId === homePageId
);
await this.handleEvent('onPageLoad', currentPageEvents);
});
await this.handleEvent('onPageLoad', currentPageEvents);
});
}
);
};

View file

@ -1256,15 +1256,12 @@ export function runQuery(
duration: notificationDuration,
});
}
const currentQueries = getCurrentState().queries;
useCurrentStateStore.getState().actions.setCurrentState({
queries: {
...currentQueries,
...getCurrentState().queries,
[queryName]: _.assign(
{
...currentQueries[queryName],
...getCurrentState().queries[queryName],
isLoading: false,
data: finalData,
rawData,
@ -1287,15 +1284,13 @@ export function runQuery(
},
});
if (mode === 'edit') {
useResolveStore.getState().actions.addAppSuggestions({
queries: {
[queryName]: {
data: finalData,
},
useResolveStore.getState().actions.addAppSuggestions({
queries: {
[queryName]: {
data: finalData,
},
});
}
},
});
resolve({ status: 'ok', data: finalData });
onEvent(_self, 'onDataQuerySuccess', queryEvents, mode);
}
@ -1940,10 +1935,10 @@ function convertMapSet(obj) {
export const checkExistingQueryName = (newName) =>
useDataQueriesStore.getState().dataQueries.some((query) => query.name === newName);
export const runQueries = (queries, _ref, mode = 'edit', isOnLoad = false) => {
export const runQueries = (queries, _ref, isOnLoad = false) => {
queries.forEach((query) => {
if (query.options.runOnPageLoad && isQueryRunnable(query)) {
runQuery(_ref, query.id, query.name, undefined, mode, isOnLoad);
runQuery(_ref, query.id, query.name, isOnLoad);
}
});
};

View file

@ -56,7 +56,7 @@ export const useAppDataStore = create(
let updateDiff = appDefinitionDiff.updateDiff;
if (appDefinitionDiff.operation === 'update') {
updateDiff = useResolveStore.getState().actions.findAndReplaceReferences(updateDiff);
updateDiff = useResolveStore.getState().actions.findReferences(updateDiff);
}
appVersionService
@ -91,7 +91,7 @@ export const useAppDataStore = create(
const appId = get().appId;
const versionId = get().currentVersionId;
const entityIdMappingData = useResolveStore.getState().actions.findAndReplaceReferences(events);
const entityIdMappingData = useResolveStore.getState().actions.findReferences(events);
const response = await appVersionService.saveAppVersionEventHandlers(
appId,
@ -111,9 +111,13 @@ export const useAppDataStore = create(
}
});
const entityReferencesInEvents = findAllEntityReferences(updatedEvents, [])?.filter(
(entity) => entity && isValidUUID(entity)
);
const entityReferencesInEvents = findAllEntityReferences(updatedEvents, [])
?.map((entity) => {
if (entity && isValidUUID(entity)) {
return entity;
}
})
?.filter((e) => e !== undefined);
const manager = useResolveStore.getState().referenceMapper;
let newEvents = JSON.parse(JSON.stringify(updatedEvents));

View file

@ -1,9 +1,11 @@
import { create, findAllEntityReferences, zustandDevTools } from './utils';
import { create, zustandDevTools } from './utils';
import { getDefaultOptions } from './storeHelper';
import { dataqueryService } from '@/_services';
// import debounce from 'lodash/debounce';
import { useAppDataStore } from '@/_stores/appDataStore';
import { useQueryPanelStore } from '@/_stores/queryPanelStore';
import { useAppVersionStore } from '@/_stores/appVersionStore';
import { runQueries } from '@/_helpers/appUtils';
import { v4 as uuidv4 } from 'uuid';
import { toast } from 'react-hot-toast';
import _, { isEmpty, throttle } from 'lodash';
@ -112,15 +114,10 @@ export const useDataQueriesStore = create(
set({ dataQueries });
if (type === 'mappingUpdate') {
const { actions } = useQueryPanelStore.getState();
actions.setSelectedQuery(null);
const queryId = dataQueries[0]?.id;
return new Promise((resolve) => {
actions.setSelectedQuery(null);
resolve();
}).then(() => {
const queryId = dataQueries[0]?.id;
actions.setSelectedQuery(queryId);
});
actions.setSelectedQuery(queryId);
}
},
deleteDataQueries: (queryId) => {
@ -154,30 +151,6 @@ export const useDataQueriesStore = create(
}, {}),
});
const newAppDefinition = JSON.parse(JSON.stringify(useEditorStore.getState().appDefinition));
const currentPageId = useEditorStore.getState().currentPageId;
const currentComponents = newAppDefinition.pages[currentPageId].components;
const newComponentDefinition = useResolveStore
.getState()
.actions.findAndReplaceReferences(currentComponents, [deletedQueryName]);
const entityReferencesInQuerries = findAllEntityReferences(get().dataQueries, []);
if (entityReferencesInQuerries.length > 0) {
const newDataQueries = useResolveStore
.getState()
.actions.findAndReplaceReferences(get().dataQueries, [deletedQueryName]);
get().actions.setDataQueries(newDataQueries, 'mappingUpdate');
}
newAppDefinition.pages[currentPageId].components = newComponentDefinition;
useEditorStore.getState().actions.updateEditorState({
appDefinition: newAppDefinition,
isUpdatingEditorStateInProcess: true,
});
const referenceManager = useResolveStore.getState().referenceMapper;
referenceManager.delete(queryId);
@ -504,7 +477,7 @@ export const useDataQueriesStore = create(
set({ queuedActions: { ...get().queuedActions, saveData: newValues } });
return;
}
const entityIdMappedOptions = useResolveStore.getState().actions.findAndReplaceReferences(newValues?.options);
const entityIdMappedOptions = useResolveStore.getState().actions.findReferences(newValues?.options);
useAppDataStore.getState().actions.setIsSaving(true);
set({ isUpdatingQueryInProcess: true });

View file

@ -185,19 +185,8 @@ export const useResolveStore = create(
return get().referenceMapper;
},
getEntityId: (entityName) => {
const { referenceMapper } = get();
for (const [key, value] of referenceMapper._map) {
if (value === entityName) {
return referenceMapper.reverseGet(key);
}
}
},
findAndReplaceReferences: (obj, targetEntityNames = []) => {
const entityNameReferences =
targetEntityNames.length === 0 ? findAllEntityReferences(obj, []) : targetEntityNames;
findReferences: (obj) => {
const entityNameReferences = findAllEntityReferences(obj, []);
if (entityNameReferences.length === 0) return obj;

View file

@ -1,53 +0,0 @@
export function updateEntityReferences(node, resourceMapping: Record<string, string> = {}) {
if (typeof node === 'object') {
for (const key in node) {
let value = node[key];
if (typeof value === 'string' && value.includes('{{') && value.includes('}}')) {
const referenceExists = value;
if (referenceExists) {
const ref = value.replace('{{', '').replace('}}', '');
const entityName = ref.split('.')[1];
if (resourceMapping[entityName]) {
const newValue = value.replace(entityName, resourceMapping[entityName]);
node[key] = newValue;
}
}
} else if (typeof value === 'object') {
value = updateEntityReferences(value, resourceMapping);
}
}
}
return node;
}
export function findAllEntityReferences(node, allRefs): [] {
if (typeof node === 'object') {
for (const key in node) {
const value = node[key];
if (typeof value === 'string' && value.includes('{{') && value.includes('}}')) {
const referenceExists = value;
if (referenceExists) {
const ref = value.replace('{{', '').replace('}}', '');
const entityName = ref.split('.')[1];
allRefs.push(entityName);
}
} else if (typeof value === 'object') {
findAllEntityReferences(value, allRefs);
}
}
}
return allRefs;
}
export function isValidUUID(uuid) {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return uuidRegex.test(uuid);
}

View file

@ -32,7 +32,6 @@ import { Component } from 'src/entities/component.entity';
import { Layout } from 'src/entities/layout.entity';
import { EventHandler, Target } from 'src/entities/event_handler.entity';
import { v4 as uuid } from 'uuid';
import { findAllEntityReferences, isValidUUID, updateEntityReferences } from 'src/helpers/import_export.helpers';
interface AppResourceMappings {
defaultDataSourceIdMapping: Record<string, string>;
@ -238,20 +237,21 @@ export class AppImportExportService {
? true
: isTooljetVersionWithNormalizedAppDefinitionSchem(importedAppTooljetVersion);
const shouldUpdateForGridCompatibility = !cloning;
const importedApp = await this.createImportedAppForUser(this.entityManager, schemaUnifiedAppParams, user);
const resourceMapping = await this.setupImportedAppAssociations(
await this.setupImportedAppAssociations(
this.entityManager,
importedApp,
schemaUnifiedAppParams,
user,
externalResourceMappings,
isNormalizedAppDefinitionSchema,
shouldUpdateForGridCompatibility,
tooljetVersion
);
await this.createAdminGroupPermissions(this.entityManager, importedApp);
await this.updateEntityReferencesForImportedApp(this.entityManager, resourceMapping);
// NOTE: App slug updation callback doesn't work while wrapped in transaction
// hence updating slug explicitly
@ -262,64 +262,6 @@ export class AppImportExportService {
return importedApp;
}
async updateEntityReferencesForImportedApp(manager: EntityManager, resourceMapping: AppResourceMappings) {
const mappings = { ...resourceMapping.componentsMapping, ...resourceMapping.dataQueryMapping };
const newComponentIds = Object.values(resourceMapping.componentsMapping);
const newQueriesIds = Object.values(resourceMapping.dataQueryMapping);
if (newComponentIds.length > 0) {
const components = await manager
.createQueryBuilder(Component, 'components')
.where('components.id IN(:...componentIds)', { componentIds: newComponentIds })
.select([
'components.id',
'components.properties',
'components.styles',
'components.general',
'components.validation',
'components.generalStyles',
'components.displayPreferences',
])
.getMany();
const toUpdateComponents = components.filter((component) => {
const entityReferencesInComponentDefinitions = findAllEntityReferences(component, []).filter(
(entity) => entity && isValidUUID(entity)
);
if (entityReferencesInComponentDefinitions.length > 0) {
return updateEntityReferences(component, mappings);
}
});
if (!isEmpty(toUpdateComponents)) {
await manager.save(toUpdateComponents);
}
}
if (newQueriesIds.length > 0) {
const dataQueries = await manager
.createQueryBuilder(DataQuery, 'dataQueries')
.where('dataQueries.id IN(:...dataQueryIds)', { dataQueryIds: newQueriesIds })
.select(['dataQueries.id', 'dataQueries.options'])
.getMany();
const toUpdateDataQueries = dataQueries.filter((dataQuery) => {
const entityReferencesInQueryOptions = findAllEntityReferences(dataQuery, []).filter(
(entity) => entity && isValidUUID(entity)
);
if (entityReferencesInQueryOptions.length > 0) {
return updateEntityReferences(dataQuery, mappings);
}
});
if (!isEmpty(toUpdateDataQueries)) {
await manager.save(toUpdateDataQueries);
}
}
}
async createImportedAppForUser(manager: EntityManager, appParams: any, user: User): Promise<App> {
return await catchDbException(async () => {
const importedApp = manager.create(App, {
@ -386,6 +328,7 @@ export class AppImportExportService {
user: User,
externalResourceMappings: Record<string, unknown>,
isNormalizedAppDefinitionSchema: boolean,
shouldUpdateForGridCompatibility: boolean,
tooljetVersion: string
) {
// Old version without app version
@ -450,6 +393,7 @@ export class AppImportExportService {
importingPages,
importingComponents,
importingEvents,
shouldUpdateForGridCompatibility,
tooljetVersion
);
@ -655,6 +599,7 @@ export class AppImportExportService {
importingPages: Page[],
importingComponents: Component[],
importingEvents: EventHandler[],
shouldUpdateForGridCompatibility: boolean,
tooljetVersion: string
): Promise<AppResourceMappings> {
appResourceMappings = { ...appResourceMappings };
@ -949,6 +894,18 @@ export class AppImportExportService {
);
}
// const appVersionIds = Object.values(appResourceMappings.appVersionMapping);
// for (const appVersionId of appVersionIds) {
// await this.updateEventActionsForNewVersionWithNewMappingIds(
// manager,
// appVersionId,
// appResourceMappings.dataQueryMapping,
// appResourceMappings.componentsMapping,
// appResourceMappings.pagesMapping
// );
// }
return appResourceMappings;
}
@ -1699,10 +1656,9 @@ export class AppImportExportService {
.createQueryBuilder(EventHandler, 'event')
.where('event.appVersionId = :versionId', { versionId })
.getMany();
const mappings = { ...oldDataQueryToNewMapping, ...oldComponentToNewComponentMapping } as Record<string, string>;
for (const event of allEvents) {
const eventDefinition = updateEntityReferences(event.event, mappings);
const eventDefinition = event.event;
if (eventDefinition?.actionId === 'run-query' && oldDataQueryToNewMapping[eventDefinition.queryId]) {
eventDefinition.queryId = oldDataQueryToNewMapping[eventDefinition.queryId];