From 0d3567d06bfc9c7d38dc345f8e905fe4b081d749 Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 14:30:00 +0530 Subject: [PATCH 01/10] fixes: component deletion fixes --- frontend/src/Editor/Inspector/Inspector.jsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/frontend/src/Editor/Inspector/Inspector.jsx b/frontend/src/Editor/Inspector/Inspector.jsx index f08f02424b..b98ae05050 100644 --- a/frontend/src/Editor/Inspector/Inspector.jsx +++ b/frontend/src/Editor/Inspector/Inspector.jsx @@ -99,13 +99,6 @@ export const Inspector = ({ componentNameRef.current = newComponentName; }, [newComponentName]); - useEffect(() => { - return () => { - handleComponentNameChange(componentNameRef.current); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const validateComponentName = (name) => { const isValid = !Object.values(allComponents) .map((component) => component.component.name) From 0117c90f5f0fdbe90a7e2a5b138cc801b7a25883 Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 16:37:45 +0530 Subject: [PATCH 02/10] fixes: cloning components to a new version should also create associated events --- frontend/src/Editor/EditorFunc.jsx | 37 +++++++++----------- frontend/src/_services/appVersion.service.js | 15 ++++++++ server/src/controllers/apps.controller.v2.ts | 21 +++++++++++ 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/frontend/src/Editor/EditorFunc.jsx b/frontend/src/Editor/EditorFunc.jsx index ef57fd09de..038fd27949 100644 --- a/frontend/src/Editor/EditorFunc.jsx +++ b/frontend/src/Editor/EditorFunc.jsx @@ -871,33 +871,28 @@ const EditorComponent = (props) => { const newComponentIds = Object.keys(componentUpdateDiff); - const mappedEvents = []; - newComponentIds.forEach((componentId) => { const sourceComponentId = getKeyFromComponentMap(componentMap, componentId); if (!sourceComponentId) return; - const componentEvents = events.filter((event) => event.sourceId === sourceComponentId); + appVersionService + .findAllEventsWithSourceId(appId, currentVersionId, sourceComponentId) + .then((componentEvents) => { + if (!componentEvents) return; + componentEvents.forEach((event) => { + const newEvent = { + event: { + ...event?.event, + }, + eventType: event?.target, + attachedTo: componentMap[event?.sourceId], + index: event?.index, + }; - mappedEvents.push(...componentEvents); + createAppVersionEventHandlers(newEvent); + }); + }); }); - - if (mappedEvents.length === 0) return; - - return Promise.all( - mappedEvents.map((event) => { - const newEvent = { - event: { - ...event?.event, - }, - eventType: event?.target, - attachedTo: componentMap[event?.sourceId], - index: event?.index, - }; - - createAppVersionEventHandlers(newEvent); - }) - ); }; const saveEditingVersion = (isUserSwitchedVersion = false) => { diff --git a/frontend/src/_services/appVersion.service.js b/frontend/src/_services/appVersion.service.js index f55fb9a115..69e4a9eba2 100644 --- a/frontend/src/_services/appVersion.service.js +++ b/frontend/src/_services/appVersion.service.js @@ -13,6 +13,7 @@ export const appVersionService = { createAppVersionEventHandler, deleteAppVersionEventHandler, clonePage, + findAllEventsWithSourceId, }; function getAll(appId) { @@ -155,3 +156,17 @@ function clonePage(appId, versionId, pageId) { handleResponse ); } + +function findAllEventsWithSourceId(appId, versionId, sourceId) { + const requestOptions = { + method: 'GET', + headers: authHeader(), + credentials: 'include', + }; + + return fetch( + `${config.apiUrl}/v2/apps/${appId}/versions/${versionId}/events${sourceId ? `?sourceId=${sourceId}` : ''} + `, + requestOptions + ).then(handleResponse); +} diff --git a/server/src/controllers/apps.controller.v2.ts b/server/src/controllers/apps.controller.v2.ts index aa3b791466..5d3e3ff4f9 100644 --- a/server/src/controllers/apps.controller.v2.ts +++ b/server/src/controllers/apps.controller.v2.ts @@ -406,6 +406,27 @@ export class AppsControllerV2 { } // events api + + @UseGuards(JwtAuthGuard) + @UseInterceptors(ValidAppInterceptor) + @Get(':id/versions/:versionId/events') + async getEvents(@User() user, @Param('id') id, @Param('versionId') versionId, @Query('sourceId') sourceId) { + const version = await this.appsService.findVersion(versionId); + const app = version.app; + + if (app.id !== id) { + throw new BadRequestException(); + } + + const ability = await this.appsAbilityFactory.appsActions(user, id); + + if (!ability.can('viewApp', app)) { + throw new ForbiddenException('You do not have permissions to perform this action'); + } + + return this.eventService.findAllEventsWithSourceId(sourceId); + } + @UseGuards(JwtAuthGuard) @UseInterceptors(ValidAppInterceptor) @Post(':id/versions/:versionId/events') From 2f45015ec2ab443726c98bb74ce8697a6bb1133a Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 16:52:24 +0530 Subject: [PATCH 03/10] fixes: creating components on cloning with general styles or properties --- server/src/services/components.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/services/components.service.ts b/server/src/services/components.service.ts index 52edd6b115..476137c20c 100644 --- a/server/src/services/components.service.ts +++ b/server/src/services/components.service.ts @@ -199,6 +199,8 @@ export class ComponentsService { transformedComponent.styles = componentData.styles || {}; transformedComponent.validation = componentData.validation || {}; transformedComponent.displayPreferences = componentData.others || null; + transformedComponent.general = componentData.general || null; + transformedComponent.generalStyles = componentData.generalStyles || null; transformedComponents.push(transformedComponent); } From 2f362ce0ce18d6b14ba6aa37aac39fedd60c1c29 Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 16:54:32 +0530 Subject: [PATCH 04/10] fixes: creatinng general properties on version --- server/src/services/apps.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/services/apps.service.ts b/server/src/services/apps.service.ts index 92df0026d2..2d18fdc33e 100644 --- a/server/src/services/apps.service.ts +++ b/server/src/services/apps.service.ts @@ -533,6 +533,8 @@ export class AppsService { newComponent.properties = component.properties; newComponent.styles = component.styles; newComponent.validation = component.validation; + newComponent.general = component.general; + newComponent.generalStyles = component.generalStyles; newComponent.parent = component.parent ? parentId : null; newComponent.page = savedPage; From 90a5b6087b1c250b3249af38fd6ee8655c79803d Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 17:02:42 +0530 Subject: [PATCH 05/10] fixes: imported app --- server/src/services/app_import_export.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/src/services/app_import_export.service.ts b/server/src/services/app_import_export.service.ts index 259ab9587a..7c82f29172 100644 --- a/server/src/services/app_import_export.service.ts +++ b/server/src/services/app_import_export.service.ts @@ -1508,6 +1508,9 @@ function transformComponentData(data: object, componentEvents: any[]): Component transformedComponent.properties = componentData.definition.properties || {}; transformedComponent.styles = componentData.definition.styles || {}; transformedComponent.validation = componentData.definition.validation || {}; + transformedComponent.general = componentData.definition.general || {}; + transformedComponent.generalStyles = componentData.definition.generalStyles || {}; + transformedComponent.displayPreferences = componentData.definition.others || {}; transformedComponent.parent = data[componentId].parent || null; transformedComponents.push(transformedComponent); From ff46eea157ce5dda7816b3981439e8cb25e0be1b Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 17:03:30 +0530 Subject: [PATCH 06/10] fixes added to app migrations --- .../1697473340856-MigrateAppsDefinitionSchemaTransition.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/data-migrations/1697473340856-MigrateAppsDefinitionSchemaTransition.ts b/server/data-migrations/1697473340856-MigrateAppsDefinitionSchemaTransition.ts index d90faa240a..20169cd23a 100644 --- a/server/data-migrations/1697473340856-MigrateAppsDefinitionSchemaTransition.ts +++ b/server/data-migrations/1697473340856-MigrateAppsDefinitionSchemaTransition.ts @@ -215,6 +215,9 @@ export class MigrateAppsDefinitionSchemaTransition1697473340856 implements Migra transformedComponent.properties = componentData.definition.properties || {}; transformedComponent.styles = componentData.definition.styles || {}; transformedComponent.validation = componentData.definition.validation || {}; + transformedComponent.general = componentData.definition.general || {}; + transformedComponent.generalStyles = componentData.definition.generalStyles || {}; + transformedComponent.displayPreferences = componentData.definition.others || {}; transformedComponent.parent = data[componentId].parent || null; transformedComponents.push(transformedComponent); From f83d4bc1b0fc15d90d4e41485e5ab5304054cebb Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 17:35:52 +0530 Subject: [PATCH 07/10] fixes: mobile view --- server/src/services/apps.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/services/apps.service.ts b/server/src/services/apps.service.ts index 2d18fdc33e..220f3d0978 100644 --- a/server/src/services/apps.service.ts +++ b/server/src/services/apps.service.ts @@ -535,6 +535,7 @@ export class AppsService { newComponent.validation = component.validation; newComponent.general = component.general; newComponent.generalStyles = component.generalStyles; + newComponent.displayPreferences = component.displayPreferences; newComponent.parent = component.parent ? parentId : null; newComponent.page = savedPage; From 931028ca4974c687eaa0024bdb4d05da0db1e23f Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 17 Oct 2023 17:42:38 +0530 Subject: [PATCH 08/10] fixes: Created a new version with multiple pages from second page, the new version shows the homepage with second page URL --- frontend/src/Editor/EditorFunc.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/Editor/EditorFunc.jsx b/frontend/src/Editor/EditorFunc.jsx index ef57fd09de..b483bfc6c3 100644 --- a/frontend/src/Editor/EditorFunc.jsx +++ b/frontend/src/Editor/EditorFunc.jsx @@ -716,6 +716,10 @@ const EditorComponent = (props) => { isUpdatingEditorStateInProcess: false, }); + if (versionSwitched) { + props?.navigate(`/${getWorkspaceId()}/apps/${appId}/${appJson.pages[homePageId]?.handle}`); + } + await useDataSourcesStore.getState().actions.fetchGlobalDataSources(data?.organization_id); await fetchDataSources(data.editing_version?.id); await fetchDataQueries(data.editing_version?.id, true, true); From 2763bd33add8c3704798f1a157e449c3505d2c9d Mon Sep 17 00:00:00 2001 From: arpitnath Date: Thu, 19 Oct 2023 19:51:35 +0530 Subject: [PATCH 09/10] fixes: table crash due to columnDeletionHistory saved as an object instead of an array --- frontend/src/_stores/utils.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/frontend/src/_stores/utils.js b/frontend/src/_stores/utils.js index 32a8cfb708..14dfd41a7e 100644 --- a/frontend/src/_stores/utils.js +++ b/frontend/src/_stores/utils.js @@ -112,11 +112,26 @@ export const computeComponentPropertyDiff = (appDiff, definition, opts) => { if (!opts?.isParamFromTableColumn) { return appDiff; } - const path = generatePath(appDiff, 'columns') || generatePath(appDiff, 'actions'); + const columnsPath = generatePath(appDiff, 'columns'); + const actionsPath = generatePath(appDiff, 'actions'); + const deletionHistoryPath = generatePath(appDiff, 'columnDeletionHistory'); - const value2 = getValueFromJson(definition, path); + let _diff = _.cloneDeep(appDiff); - const _diff = updateValueInJson(_.cloneDeep(appDiff), path, value2); + if (columnsPath) { + const columnsValue = getValueFromJson(definition, columnsPath); + _diff = updateValueInJson(_diff, columnsPath, columnsValue); + } + + if (actionsPath) { + const actionsValue = getValueFromJson(definition, actionsPath); + _diff = updateValueInJson(_diff, actionsPath, actionsValue); + } + + if (deletionHistoryPath) { + const deletionHistoryValue = getValueFromJson(definition, deletionHistoryPath); + _diff = updateValueInJson(_diff, deletionHistoryPath, deletionHistoryValue); + } return _diff; }; From c002faf2e867ffd4968f230c40f90bd3558154c2 Mon Sep 17 00:00:00 2001 From: Arpit Date: Fri, 20 Oct 2023 11:14:14 +0530 Subject: [PATCH 10/10] fixes: on creating new version, data_queries should be created (#7975) --- server/src/services/apps.service.ts | 110 +++++++++++++--------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/server/src/services/apps.service.ts b/server/src/services/apps.service.ts index 220f3d0978..cdbd421ee3 100644 --- a/server/src/services/apps.service.ts +++ b/server/src/services/apps.service.ts @@ -633,7 +633,7 @@ export class AppsService { where: { appVersionId: versionFrom?.id, target: 'data_query' }, }); - if (dataSources?.length) { + if (dataSources?.length > 0) { for (const dataSource of dataSources) { const dataSourceParams: Partial = { name: dataSource.name, @@ -675,71 +675,65 @@ export class AppsService { newDataQueries.push(newQuery); } } + } - if (globalQueries?.length) { - for (const globalQuery of globalQueries) { - const dataQueryParams = { - name: globalQuery.name, - options: globalQuery.options, - dataSourceId: globalQuery.dataSourceId, - appVersionId: appVersion.id, - }; + if (globalQueries?.length > 0) { + for (const globalQuery of globalQueries) { + const dataQueryParams = { + name: globalQuery.name, + options: globalQuery.options, + dataSourceId: globalQuery.dataSourceId, + appVersionId: appVersion.id, + }; - const newQuery = await manager.save(manager.create(DataQuery, dataQueryParams)); - const dataQueryEvents = allEvents.filter((event) => event.sourceId === globalQuery.id); + const newQuery = await manager.save(manager.create(DataQuery, dataQueryParams)); + const dataQueryEvents = allEvents.filter((event) => event.sourceId === globalQuery.id); - dataQueryEvents.forEach(async (event, index) => { - const newEvent = new EventHandler(); + dataQueryEvents.forEach(async (event, index) => { + const newEvent = new EventHandler(); - newEvent.id = uuid.v4(); - newEvent.name = event.name; - newEvent.sourceId = newQuery.id; - newEvent.target = event.target; - newEvent.event = event.event; - newEvent.index = event.index ?? index; - newEvent.appVersionId = appVersion.id; + newEvent.id = uuid.v4(); + newEvent.name = event.name; + newEvent.sourceId = newQuery.id; + newEvent.target = event.target; + newEvent.event = event.event; + newEvent.index = event.index ?? index; + newEvent.appVersionId = appVersion.id; - await manager.save(newEvent); - }); - oldDataQueryToNewMapping[globalQuery.id] = newQuery.id; - newDataQueries.push(newQuery); - } + await manager.save(newEvent); + }); + oldDataQueryToNewMapping[globalQuery.id] = newQuery.id; + newDataQueries.push(newQuery); } + } - for (const newQuery of newDataQueries) { - const newOptions = this.replaceDataQueryOptionsWithNewDataQueryIds( - newQuery.options, - oldDataQueryToNewMapping + for (const newQuery of newDataQueries) { + const newOptions = this.replaceDataQueryOptionsWithNewDataQueryIds(newQuery.options, oldDataQueryToNewMapping); + newQuery.options = newOptions; + + await manager.save(newQuery); + } + + appVersion.definition = this.replaceDataQueryIdWithinDefinitions(appVersion.definition, oldDataQueryToNewMapping); + await manager.save(appVersion); + + for (const appEnvironment of appEnvironments) { + for (const dataSource of dataSources) { + const dataSourceOption = await manager.findOneOrFail(DataSourceOptions, { + where: { dataSourceId: dataSource.id, environmentId: appEnvironment.id }, + }); + + const convertedOptions = this.convertToArrayOfKeyValuePairs(dataSourceOption.options); + const newOptions = await this.dataSourcesService.parseOptionsForCreate(convertedOptions, false, manager); + await this.setNewCredentialValueFromOldValue(newOptions, convertedOptions, manager); + + await manager.save( + manager.create(DataSourceOptions, { + options: newOptions, + dataSourceId: dataSourceMapping[dataSource.id], + environmentId: appEnvironment.id, + }) ); - newQuery.options = newOptions; - - await manager.save(newQuery); - } - - appVersion.definition = this.replaceDataQueryIdWithinDefinitions( - appVersion.definition, - oldDataQueryToNewMapping - ); - await manager.save(appVersion); - - for (const appEnvironment of appEnvironments) { - for (const dataSource of dataSources) { - const dataSourceOption = await manager.findOneOrFail(DataSourceOptions, { - where: { dataSourceId: dataSource.id, environmentId: appEnvironment.id }, - }); - - const convertedOptions = this.convertToArrayOfKeyValuePairs(dataSourceOption.options); - const newOptions = await this.dataSourcesService.parseOptionsForCreate(convertedOptions, false, manager); - await this.setNewCredentialValueFromOldValue(newOptions, convertedOptions, manager); - - await manager.save( - manager.create(DataSourceOptions, { - options: newOptions, - dataSourceId: dataSourceMapping[dataSource.id], - environmentId: appEnvironment.id, - }) - ); - } } } }