fixes: Resolving App Version and Timestamp Update Challenges (#7863)

This commit is contained in:
Arpit 2023-10-13 19:25:55 +05:30 committed by GitHub
parent 436980edf5
commit 75086defea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 113 additions and 72 deletions

View file

@ -188,7 +188,7 @@ export class AppsControllerV2 {
throw new ForbiddenException('You do not have permissions to perform this action');
}
await this.componentsService.update(versionEditDto.diff);
await this.componentsService.update(versionEditDto.diff, versionId);
}
@UseGuards(JwtAuthGuard)
@ -212,7 +212,7 @@ export class AppsControllerV2 {
throw new ForbiddenException('You do not have permissions to perform this action');
}
await this.componentsService.delete(versionEditDto.diff);
await this.componentsService.delete(versionEditDto.diff, versionId);
}
@UseGuards(JwtAuthGuard)
@ -236,7 +236,7 @@ export class AppsControllerV2 {
throw new ForbiddenException('You do not have permissions to perform this action');
}
await this.componentsService.componentLayoutChange(versionEditDto.diff);
await this.componentsService.componentLayoutChange(versionEditDto.diff, versionId);
}
// pages api
@ -300,7 +300,7 @@ export class AppsControllerV2 {
throw new ForbiddenException('You do not have permissions to perform this action');
}
await this.pageService.updatePage({ pageId: updatePageDto.pageId, diff: updatePageDto.diff });
await this.pageService.updatePage({ pageId: updatePageDto.pageId, diff: updatePageDto.diff }, versionId);
}
@UseGuards(JwtAuthGuard)
@ -363,7 +363,7 @@ export class AppsControllerV2 {
throw new ForbiddenException('You do not have permissions to perform this action');
}
return await this.eventService.updateEvent(body?.events, body?.updateType);
return await this.eventService.updateEvent(body?.events, body?.updateType, versionId);
}
@UseGuards(JwtAuthGuard)
@ -382,6 +382,6 @@ export class AppsControllerV2 {
throw new ForbiddenException('You do not have permissions to perform this action');
}
return await this.eventService.deleteEvent(eventId);
return await this.eventService.deleteEvent(eventId, versionId);
}
}

View file

@ -80,6 +80,26 @@ export async function dbTransactionWrap(operation: (...args) => any, manager?: E
}
}
export const updateTimestampForAppVersion = async (manager, appVersionId) => {
const appVersion = await manager.findOne('app_versions', appVersionId);
if (appVersion) {
await manager.update('app_versions', appVersionId, { updatedAt: new Date() });
}
};
export async function dbTransactionForAppVersionAssociationsUpdate(
operation: (...args) => any,
appVersionId: string
): Promise<any> {
return await getManager().transaction(async (manager) => {
const result = await operation(manager);
await updateTimestampForAppVersion(manager, appVersionId);
return result;
});
}
export const defaultAppEnvironments = [{ name: 'production', isDefault: true, priority: 3 }];
export async function catchDbException(
operation: () => any,

View file

@ -4,7 +4,7 @@ import { EntityManager, Repository } from 'typeorm';
import { Component } from 'src/entities/component.entity';
import { Layout } from 'src/entities/layout.entity';
import { Page } from 'src/entities/page.entity';
import { dbTransactionWrap } from 'src/helpers/utils.helper';
import { dbTransactionForAppVersionAssociationsUpdate, dbTransactionWrap } from 'src/helpers/utils.helper';
import { EventsService } from './events_handler.service';
@ -22,7 +22,7 @@ export class ComponentsService {
}
async create(componentDiff: object, pageId: string, appVersionId: string) {
return dbTransactionWrap(async (manager: EntityManager) => {
return dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
const page = await manager.findOne(Page, {
where: { appVersionId, id: pageId },
});
@ -58,11 +58,11 @@ export class ComponentsService {
await manager.save(Layout, componentLayouts);
return {};
});
}, appVersionId);
}
async update(componentDiff: object) {
return dbTransactionWrap(async (manager) => {
async update(componentDiff: object, appVersionId: string) {
return dbTransactionForAppVersionAssociationsUpdate(async (manager) => {
for (const componentId in componentDiff) {
const { component } = componentDiff[componentId];
@ -105,11 +105,11 @@ export class ComponentsService {
return;
}
});
}, appVersionId);
}
async delete(componentIds: string[]) {
return dbTransactionWrap(async (manager: EntityManager) => {
async delete(componentIds: string[], appVersionId: string) {
return dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
const components = await manager.findByIds(Component, componentIds);
if (!components.length) {
@ -125,11 +125,11 @@ export class ComponentsService {
});
await manager.delete(Component, componentIds);
});
}, appVersionId);
}
async componentLayoutChange(componenstLayoutDiff: object) {
return dbTransactionWrap(async (manager: EntityManager) => {
async componentLayoutChange(componenstLayoutDiff: object, appVersionId: string) {
return dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
for (const componentId in componenstLayoutDiff) {
const doesComponentExist = await manager.findAndCount(Component, { id: componentId });
@ -155,7 +155,7 @@ export class ComponentsService {
}
}
}
});
}, appVersionId);
}
async getAllComponents(pageId: string) {

View file

@ -4,7 +4,7 @@ import { EntityManager, Repository } from 'typeorm';
import { Component } from 'src/entities/component.entity';
import { EventHandler } from 'src/entities/event_handler.entity';
import { dbTransactionWrap } from 'src/helpers/utils.helper';
import { dbTransactionWrap, dbTransactionForAppVersionAssociationsUpdate } from 'src/helpers/utils.helper';
@Injectable()
export class EventsService {
@ -55,14 +55,14 @@ export class EventsService {
index: eventObj.index,
};
return await dbTransactionWrap(async (manager: EntityManager) => {
return await dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
const event = await manager.save(EventHandler, newEvent);
return event;
});
}, versionId);
}
async updateEvent(events: [], updateType: 'update' | 'reorder') {
return await dbTransactionWrap(async (manager: EntityManager) => {
async updateEvent(events: [], updateType: 'update' | 'reorder', appVersionId: string) {
return await dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
return await Promise.all(
events.map(async (event) => {
const { event_id, diff } = event as any;
@ -91,7 +91,7 @@ export class EventsService {
return await manager.save(EventHandler, updatedEvent);
})
);
});
}, appVersionId);
}
async updateEventsOrderOnDelete(sourceId: string, deletedIndex: number) {
@ -112,8 +112,8 @@ export class EventsService {
});
}
async deleteEvent(eventId: string) {
return await dbTransactionWrap(async (manager: EntityManager) => {
async deleteEvent(eventId: string, appVersionId: string) {
return await dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
const event = await manager.findOne(EventHandler, {
where: { id: eventId },
});
@ -129,6 +129,6 @@ export class EventsService {
}
await this.updateEventsOrderOnDelete(event.sourceId, event.index);
return deleteResponse;
});
}, appVersionId);
}
}

View file

@ -6,7 +6,7 @@ import { Page } from 'src/entities/page.entity';
import { ComponentsService } from './components.service';
import { CreatePageDto, UpdatePageDto } from '@dto/pages.dto';
import { AppsService } from './apps.service';
import { dbTransactionWrap } from 'src/helpers/utils.helper';
import { dbTransactionWrap, dbTransactionForAppVersionAssociationsUpdate } from 'src/helpers/utils.helper';
import { EventsService } from './events_handler.service';
import { Component } from 'src/entities/component.entity';
import { Layout } from 'src/entities/layout.entity';
@ -42,54 +42,58 @@ export class PageService {
}
async createPage(page: CreatePageDto, appVersionId: string): Promise<Page> {
const newPage = new Page();
newPage.id = page.id;
newPage.name = page.name;
newPage.handle = page.handle;
newPage.index = page.index;
newPage.appVersionId = appVersionId;
return dbTransactionForAppVersionAssociationsUpdate(async (manager) => {
const newPage = new Page();
newPage.id = page.id;
newPage.name = page.name;
newPage.handle = page.handle;
newPage.index = page.index;
newPage.appVersionId = appVersionId;
return this.pageRepository.save(newPage);
return await manager.save(Page, newPage);
}, appVersionId);
}
async clonePage(pageId: string, appVersionId: string) {
const pageToClone = await this.pageRepository.findOne(pageId);
return dbTransactionForAppVersionAssociationsUpdate(async (manager) => {
const pageToClone = await manager.findOne(Page, pageId);
if (!pageToClone) {
throw new Error('Page not found');
}
if (!pageToClone) {
throw new Error('Page not found');
}
let pageName = `${pageToClone.name} (copy)`;
let pageHandle = `${pageToClone.handle}-copy`;
let pageName = `${pageToClone.name} (copy)`;
let pageHandle = `${pageToClone.handle}-copy`;
const allPages = await this.pageRepository.find({ appVersionId });
const allPages = await this.pageRepository.find({ appVersionId });
const pageNameORHandleExists = allPages.filter((page) => {
return page.name.includes(pageName) || page.handle.includes(pageHandle);
});
const pageNameORHandleExists = allPages.filter((page) => {
return page.name.includes(pageName) || page.handle.includes(pageHandle);
});
if (pageNameORHandleExists.length > 0) {
pageName = `${pageToClone.name} (copy ${pageNameORHandleExists.length})`;
pageHandle = `${pageToClone.handle}-copy-${pageNameORHandleExists.length}`;
}
if (pageNameORHandleExists.length > 0) {
pageName = `${pageToClone.name} (copy ${pageNameORHandleExists.length})`;
pageHandle = `${pageToClone.handle}-copy-${pageNameORHandleExists.length}`;
}
const newPage = new Page();
newPage.name = pageName;
newPage.handle = pageHandle;
newPage.index = pageToClone.index + 1;
newPage.appVersionId = appVersionId;
const newPage = new Page();
newPage.name = pageName;
newPage.handle = pageHandle;
newPage.index = pageToClone.index + 1;
newPage.appVersionId = appVersionId;
const clonedpage = await this.pageRepository.save(newPage);
const clonedpage = await this.pageRepository.save(newPage);
await this.clonePageEventsAndComponents(pageId, clonedpage.id, appVersionId);
await this.clonePageEventsAndComponents(pageId, clonedpage.id);
const pages = await this.findPagesForVersion(appVersionId);
const events = await this.eventHandlerService.findEventsForVersion(appVersionId);
const pages = await this.findPagesForVersion(appVersionId);
const events = await this.eventHandlerService.findEventsForVersion(appVersionId);
return { pages, events };
return { pages, events };
}, appVersionId);
}
async clonePageEventsAndComponents(pageId: string, clonePageId: string, appVersionId: string) {
async clonePageEventsAndComponents(pageId: string, clonePageId: string) {
return dbTransactionWrap(async (manager: EntityManager) => {
const pageComponents = await manager.find(Component, { pageId });
const pageEvents = await this.eventHandlerService.findAllEventsWithSourceId(pageId);
@ -98,6 +102,14 @@ export class PageService {
// Clone events
await Promise.all(
pageEvents.map(async (event) => {
const eventDefinition = event.event;
if (eventDefinition?.actionId === 'control-component') {
eventDefinition.componentId = componentsIdMap[eventDefinition.componentId];
}
event.event = eventDefinition;
const clonedEvent = { ...event, id: undefined, sourceId: clonePageId };
await manager.save(EventHandler, clonedEvent);
})
@ -119,11 +131,20 @@ export class PageService {
// Clone component events
const clonedComponentEvents = await this.eventHandlerService.findAllEventsWithSourceId(component.id);
const clonedEvents = clonedComponentEvents.map((event) => ({
...event,
id: undefined,
sourceId: newComponent.id,
}));
const clonedEvents = clonedComponentEvents.map((event) => {
const eventDefinition = event.event;
if (eventDefinition?.actionId === 'control-component') {
eventDefinition.componentId = componentsIdMap[eventDefinition.componentId];
}
event.event = eventDefinition;
return {
...event,
id: undefined,
sourceId: newComponent.id,
};
});
await manager.save(Layout, clonedLayouts);
await manager.save(EventHandler, clonedEvents);
@ -141,9 +162,9 @@ export class PageService {
});
}
async updatePage(pageUpdates: UpdatePageDto) {
async updatePage(pageUpdates: UpdatePageDto, appVersionId: string) {
if (Object.keys(pageUpdates.diff).length > 1) {
return this.updatePagesOrder(pageUpdates.diff);
return this.updatePagesOrder(pageUpdates.diff, appVersionId);
}
const currentPage = await this.pageRepository.findOne(pageUpdates.pageId);
@ -154,7 +175,7 @@ export class PageService {
return this.pageRepository.update(pageUpdates.pageId, pageUpdates.diff);
}
async updatePagesOrder(pages) {
async updatePagesOrder(pages, appVersionId: string) {
const pagesToPage = Object.keys(pages).map((pageId) => {
return {
id: pageId,
@ -162,18 +183,18 @@ export class PageService {
};
});
return await dbTransactionWrap(async (manager: EntityManager) => {
return await dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
await Promise.all(
pagesToPage.map(async (page) => {
await manager.update(Page, page.id, page);
})
);
});
}, appVersionId);
}
async deletePage(pageId: string, appVersionId: string) {
const { editingVersion } = await this.appService.findAppFromVersion(appVersionId);
return dbTransactionWrap(async (manager: EntityManager) => {
return dbTransactionForAppVersionAssociationsUpdate(async (manager: EntityManager) => {
const pageExists = await manager.findOne(Page, pageId);
if (!pageExists) {
@ -200,7 +221,7 @@ export class PageService {
await manager.update(Page, page.id, page);
})
);
});
}, appVersionId);
}
rearrangePagesOnDelete(pages: Page[], pageDeletedIndex: number) {