mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 17:08:34 +00:00
new v2 controllers for apps
This commit is contained in:
parent
08274d53ff
commit
c5167203f5
11 changed files with 412 additions and 113 deletions
|
|
@ -1161,6 +1161,8 @@ const EditorComponent = (props) => {
|
|||
return;
|
||||
}
|
||||
|
||||
setCurrentPageId(pageId);
|
||||
|
||||
const copyOfAppDefinition = JSON.parse(JSON.stringify(appDefinition));
|
||||
|
||||
copyOfAppDefinition.pages[pageId].name = newName;
|
||||
|
|
@ -1192,12 +1194,17 @@ const EditorComponent = (props) => {
|
|||
name,
|
||||
handle: newHandle,
|
||||
components: {},
|
||||
index: Object.keys(copyOfAppDefinition.pages).length,
|
||||
index: Object.keys(copyOfAppDefinition.pages).length + 1,
|
||||
};
|
||||
|
||||
setCurrentPageId(newPageId);
|
||||
|
||||
appDefinitionChanged(copyOfAppDefinition, { pageDefinitionChanged: true, switchPage: true, pageId: newPageId });
|
||||
appDefinitionChanged(copyOfAppDefinition, {
|
||||
pageDefinitionChanged: true,
|
||||
addNewPage: true,
|
||||
switchPage: true,
|
||||
pageId: newPageId,
|
||||
});
|
||||
};
|
||||
|
||||
const switchPage = (pageId, queryParams = []) => {
|
||||
|
|
@ -1288,6 +1295,7 @@ const EditorComponent = (props) => {
|
|||
|
||||
appDefinitionChanged(newAppDefinition, {
|
||||
pageDefinitionChanged: true,
|
||||
deletePageRequest: true,
|
||||
});
|
||||
|
||||
toast.success(`${toBeDeletedPage.name} page deleted.`);
|
||||
|
|
@ -1447,7 +1455,7 @@ const EditorComponent = (props) => {
|
|||
const pagesObj = newSortedPages.reduce((acc, page, index) => {
|
||||
acc[page.id] = {
|
||||
...page,
|
||||
index: index,
|
||||
index: index + 1,
|
||||
};
|
||||
return acc;
|
||||
}, {});
|
||||
|
|
@ -1458,6 +1466,7 @@ const EditorComponent = (props) => {
|
|||
|
||||
appDefinitionChanged(newAppDefinition, {
|
||||
pageDefinitionChanged: true,
|
||||
pageSortingChanged: true,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,15 @@ function autoSaveApp(appId, versionId, diff, type, pageId, operation, isUserSwit
|
|||
delete: 'DELETE',
|
||||
});
|
||||
|
||||
const body = { is_user_switched_version: isUserSwitchedVersion, pageId, diff: diff };
|
||||
let body = {};
|
||||
|
||||
if ((type === 'pages' && operation === 'create') || operation === 'delete') {
|
||||
body = {
|
||||
...diff,
|
||||
};
|
||||
} else {
|
||||
body = { is_user_switched_version: isUserSwitchedVersion, pageId, diff: diff };
|
||||
}
|
||||
|
||||
const requestOptions = {
|
||||
method: OPERATION[operation],
|
||||
|
|
@ -74,5 +82,5 @@ function autoSaveApp(appId, versionId, diff, type, pageId, operation, isUserSwit
|
|||
credentials: 'include',
|
||||
body: JSON.stringify(body),
|
||||
};
|
||||
return fetch(`${config.apiUrl}/apps/${appId}/versions/${versionId}/${type}`, requestOptions).then(handleResponse);
|
||||
return fetch(`${config.apiUrl}/v2/apps/${appId}/versions/${versionId}/${type}`, requestOptions).then(handleResponse);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,12 +48,31 @@ export const computeAppDiff = (appDiff, currentPageId, opts) => {
|
|||
let updateDiff;
|
||||
let operation = 'update';
|
||||
|
||||
console.log('---piku [computeAppDiff]', { appDiff, currentPageId, opts });
|
||||
if (opts?.deletePageRequest) {
|
||||
const deletePageId = _.keys(appDiff?.pages).map((pageId) => {
|
||||
if (appDiff?.pages[pageId]?.pageId === undefined) {
|
||||
return pageId;
|
||||
}
|
||||
})[0];
|
||||
|
||||
if (opts?.pageDefinitionChanged) {
|
||||
updateDiff = {
|
||||
pageId: deletePageId,
|
||||
};
|
||||
|
||||
type = updateType.pageDefinitionChanged;
|
||||
operation = 'delete';
|
||||
} else if (opts?.pageSortingChanged) {
|
||||
updateDiff = appDiff?.pages;
|
||||
|
||||
type = updateType.pageDefinitionChanged;
|
||||
} else if (opts?.pageDefinitionChanged) {
|
||||
updateDiff = appDiff?.pages[currentPageId];
|
||||
|
||||
type = updateType.pageDefinitionChanged;
|
||||
|
||||
if (opts?.addNewPage) {
|
||||
operation = 'create';
|
||||
}
|
||||
} else if (opts?.componentDeleted) {
|
||||
const currentPageComponents = appDiff?.pages[currentPageId]?.components;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ export class CreatePageTable1691004576333 implements MigrationInterface {
|
|||
type: 'varchar',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'index',
|
||||
type: 'int',
|
||||
isNullable: false,
|
||||
},
|
||||
{
|
||||
name: 'page_handle',
|
||||
type: 'varchar',
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import { EntityManager } from 'typeorm';
|
|||
import { ValidAppInterceptor } from 'src/interceptors/valid.app.interceptor';
|
||||
import { AppDecorator } from 'src/decorators/app.decorator';
|
||||
|
||||
import { ComponentsService } from '@services/components.service';
|
||||
import { PageService } from '@services/page.service';
|
||||
|
||||
@Controller('apps')
|
||||
|
|
@ -36,7 +35,6 @@ export class AppsController {
|
|||
constructor(
|
||||
private appsService: AppsService,
|
||||
private foldersService: FoldersService,
|
||||
private componentsService: ComponentsService,
|
||||
private pageService: PageService,
|
||||
private appsAbilityFactory: AppsAbilityFactory
|
||||
) {}
|
||||
|
|
@ -323,100 +321,6 @@ export class AppsController {
|
|||
await this.appsService.updateVersion(version, versionEditDto, app.organizationId);
|
||||
return;
|
||||
}
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Post(':id/versions/:versionId/components')
|
||||
async createComponent(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.create(versionEditDto.diff, versionEditDto.pageId);
|
||||
}
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Put(':id/versions/:versionId/components')
|
||||
async updateComponent(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.update(versionEditDto.diff);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Delete(':id/versions/:versionId/components')
|
||||
async deleteComponents(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.delete(versionEditDto.diff);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Put(':id/versions/:versionId/components/layout')
|
||||
async updateComponentLayput(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.componentLayoutChange(versionEditDto.diff);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,262 @@
|
|||
import { Controller } from '@nestjs/common';
|
||||
// import { JwtAuthGuard } from '../../src/modules/auth/jwt-auth.guard';
|
||||
import {
|
||||
Controller,
|
||||
ForbiddenException,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Query,
|
||||
UseGuards,
|
||||
Body,
|
||||
BadRequestException,
|
||||
UseInterceptors,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../src/modules/auth/jwt-auth.guard';
|
||||
import { AppsService } from '../services/apps.service';
|
||||
import { camelizeKeys, decamelizeKeys } from 'humps';
|
||||
import { AppsAbilityFactory } from 'src/modules/casl/abilities/apps-ability.factory';
|
||||
// import { AppAuthGuard } from 'src/modules/auth/app-auth.guard';
|
||||
import { App } from 'src/entities/app.entity';
|
||||
import { User } from 'src/decorators/user.decorator';
|
||||
|
||||
import { VersionEditDto } from '@dto/version-edit.dto';
|
||||
import { CreatePageDto, UpdatePageDto } from '@dto/pages.dto';
|
||||
|
||||
import { ValidAppInterceptor } from 'src/interceptors/valid.app.interceptor';
|
||||
import { AppDecorator } from 'src/decorators/app.decorator';
|
||||
|
||||
import { ComponentsService } from '@services/components.service';
|
||||
import { PageService } from '@services/page.service';
|
||||
|
||||
@Controller({
|
||||
path: 'apps',
|
||||
version: '2', // Set the version to '2'
|
||||
version: '2',
|
||||
})
|
||||
export class AppsControllerV2 {
|
||||
constructor(/* Add your services and dependencies here */) {}
|
||||
constructor(
|
||||
private appsService: AppsService,
|
||||
private componentsService: ComponentsService,
|
||||
private pageService: PageService,
|
||||
private appsAbilityFactory: AppsAbilityFactory
|
||||
) {}
|
||||
|
||||
// Add your new version 2 methods here
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Get(':id')
|
||||
async show(@User() user, @AppDecorator() app: App, @Query('access_type') accessType: string) {
|
||||
const ability = await this.appsAbilityFactory.appsActions(user, app.id);
|
||||
if (!ability.can('viewApp', app)) {
|
||||
throw new ForbiddenException(
|
||||
JSON.stringify({
|
||||
organizationId: app.organizationId,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (accessType === 'edit' && !ability.can('editApp', app)) {
|
||||
throw new ForbiddenException(
|
||||
JSON.stringify({
|
||||
organizationId: app.organizationId,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const response = decamelizeKeys(app);
|
||||
|
||||
const seralizedQueries = [];
|
||||
const dataQueriesForVersion = app.editingVersion
|
||||
? await this.appsService.findDataQueriesForVersion(app.editingVersion.id)
|
||||
: [];
|
||||
|
||||
const pagesForVersion = app.editingVersion ? await this.pageService.findPagesForVersion(app.editingVersion.id) : [];
|
||||
|
||||
// serialize queries
|
||||
for (const query of dataQueriesForVersion) {
|
||||
const decamelizedQuery = decamelizeKeys(query);
|
||||
decamelizedQuery['options'] = query.options;
|
||||
seralizedQueries.push(decamelizedQuery);
|
||||
}
|
||||
|
||||
response['data_queries'] = seralizedQueries;
|
||||
response['definition'] = app.editingVersion?.definition;
|
||||
response['pages'] = pagesForVersion;
|
||||
|
||||
//! if editing version exists, camelize the definition
|
||||
if (app.editingVersion && app.editingVersion.definition) {
|
||||
response['editing_version'] = {
|
||||
...response['editing_version'],
|
||||
definition: camelizeKeys(app.editingVersion.definition),
|
||||
};
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
//components api
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Post(':id/versions/:versionId/components')
|
||||
async createComponent(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.create(versionEditDto.diff, versionEditDto.pageId);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Put(':id/versions/:versionId/components')
|
||||
async updateComponent(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.update(versionEditDto.diff);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Delete(':id/versions/:versionId/components')
|
||||
async deleteComponents(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.delete(versionEditDto.diff);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Put(':id/versions/:versionId/components/layout')
|
||||
async updateComponentLayout(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() versionEditDto: VersionEditDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.componentsService.componentLayoutChange(versionEditDto.diff);
|
||||
}
|
||||
|
||||
// pages api
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Post(':id/versions/:versionId/pages')
|
||||
async createPages(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() createPageDto: CreatePageDto
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.pageService.createPage(createPageDto, versionId);
|
||||
}
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Put(':id/versions/:versionId/pages')
|
||||
async updatePages(
|
||||
@User() user,
|
||||
@Param('id') id,
|
||||
@Param('versionId') versionId,
|
||||
@Body() updatePageDto: Partial<UpdatePageDto>
|
||||
) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
await this.pageService.updatePage({ pageId: updatePageDto.pageId, diff: updatePageDto.diff });
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseInterceptors(ValidAppInterceptor)
|
||||
@Delete(':id/versions/:versionId/pages')
|
||||
async deletePage(@User() user, @Param('id') id, @Param('versionId') versionId, @Body() body) {
|
||||
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('updateVersions', app)) {
|
||||
throw new ForbiddenException('You do not have permissions to perform this action');
|
||||
}
|
||||
|
||||
const { pageId } = body;
|
||||
|
||||
if (pageId) {
|
||||
await this.pageService.deletePage(pageId, versionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
server/src/dto/pages.dto.ts
Normal file
17
server/src/dto/pages.dto.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { IsNumber, IsString } from 'class-validator';
|
||||
|
||||
export class CreatePageDto {
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
@IsString()
|
||||
handle: string;
|
||||
|
||||
@IsNumber()
|
||||
index: number;
|
||||
}
|
||||
|
||||
export class UpdatePageDto {
|
||||
pageId: string;
|
||||
diff: Partial<CreatePageDto>;
|
||||
}
|
||||
|
|
@ -11,7 +11,10 @@ export class Page {
|
|||
name: string;
|
||||
|
||||
@Column({ name: 'page_handle' })
|
||||
pageHandle: string;
|
||||
handle: string;
|
||||
|
||||
@Column()
|
||||
index: number;
|
||||
|
||||
@Column({ name: 'app_version_id' })
|
||||
appVersionId: string;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||
import { App } from '../../entities/app.entity';
|
||||
import { File } from '../../entities/file.entity';
|
||||
import { AppsController } from '../../controllers/apps.controller';
|
||||
import { AppsControllerV2 } from '../../controllers/apps.controller.v2';
|
||||
import { AppsService } from '../../services/apps.service';
|
||||
import { AppVersion } from '../../../src/entities/app_version.entity';
|
||||
import { DataQuery } from '../../../src/entities/data_query.entity';
|
||||
|
|
@ -83,6 +84,6 @@ import { PageService } from '@services/page.service';
|
|||
ComponentsService,
|
||||
PageService,
|
||||
],
|
||||
controllers: [AppsController, AppUsersController, AppsImportExportController],
|
||||
controllers: [AppsController, AppsControllerV2, AppUsersController, AppsImportExportController],
|
||||
})
|
||||
export class AppsModule {}
|
||||
|
|
|
|||
|
|
@ -123,8 +123,9 @@ export class AppsService {
|
|||
const defaultHomePage = await manager.save(
|
||||
manager.create(Page, {
|
||||
name: 'Defualt Page',
|
||||
pageHandle: 'defaultpage',
|
||||
handle: 'defaultpage',
|
||||
appVersionId: appVersion.id,
|
||||
index: 1,
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,15 +4,18 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||
|
||||
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';
|
||||
|
||||
@Injectable()
|
||||
export class PageService {
|
||||
constructor(
|
||||
private readonly manager: EntityManager,
|
||||
@InjectRepository(Page)
|
||||
private readonly pageRepository: Repository<Page>,
|
||||
|
||||
private componentsService: ComponentsService
|
||||
private componentsService: ComponentsService,
|
||||
private appService: AppsService
|
||||
) {}
|
||||
|
||||
async findPagesForVersion(appVersionId: string): Promise<Page[]> {
|
||||
|
|
@ -32,4 +35,83 @@ export class PageService {
|
|||
async findOne(id: string): Promise<Page> {
|
||||
return this.pageRepository.findOne(id);
|
||||
}
|
||||
|
||||
async createPage(page: CreatePageDto, appVersionId: string): Promise<Page> {
|
||||
const newPage = {
|
||||
...page,
|
||||
appVersionId: appVersionId,
|
||||
};
|
||||
|
||||
return this.pageRepository.save(newPage);
|
||||
}
|
||||
|
||||
async updatePage(pageUpdates: UpdatePageDto) {
|
||||
if (Object.keys(pageUpdates.diff).length > 1) {
|
||||
return this.updatePagesOrder(pageUpdates.diff);
|
||||
}
|
||||
|
||||
const currentPage = await this.pageRepository.findOne(pageUpdates.pageId);
|
||||
|
||||
if (!currentPage) {
|
||||
throw new Error('Page not found');
|
||||
}
|
||||
return this.pageRepository.update(pageUpdates.pageId, pageUpdates.diff);
|
||||
}
|
||||
|
||||
async updatePagesOrder(pages) {
|
||||
const pagesToPage = Object.keys(pages).map((pageId) => {
|
||||
return {
|
||||
id: pageId,
|
||||
index: pages[pageId].index,
|
||||
};
|
||||
});
|
||||
|
||||
return await dbTransactionWrap(async (manager: EntityManager) => {
|
||||
await Promise.all(
|
||||
pagesToPage.map(async (page) => {
|
||||
await manager.update(Page, page.id, page);
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async deletePage(pageId: string, appVersionId: string) {
|
||||
const pageExists = await this.pageRepository.findOne(pageId);
|
||||
const { editingVersion } = await this.appService.findAppFromVersion(appVersionId);
|
||||
|
||||
if (!pageExists) {
|
||||
throw new Error('Page not found');
|
||||
}
|
||||
|
||||
if (editingVersion?.homePageId === pageId) {
|
||||
throw new Error('Cannot delete home page');
|
||||
}
|
||||
const pageDeletedIndex = pageExists.index;
|
||||
const pageDeleted = await this.pageRepository.delete(pageId);
|
||||
|
||||
if (pageDeleted.affected === 0) {
|
||||
throw new Error('Page not deleted');
|
||||
}
|
||||
|
||||
const pages = await this.pageRepository.find({ appVersionId: pageExists.appVersionId });
|
||||
|
||||
const rearrangedPages = this.rearrangePagesOnDelete(pages, pageDeletedIndex);
|
||||
|
||||
await this.pageRepository.save(rearrangedPages);
|
||||
}
|
||||
|
||||
rearrangePagesOnDelete(pages: Page[], pageDeletedIndex: number) {
|
||||
const rearrangedPages = pages.map((page, index) => {
|
||||
if (index + 1 >= pageDeletedIndex) {
|
||||
return {
|
||||
...page,
|
||||
index: page.index - 1,
|
||||
};
|
||||
}
|
||||
|
||||
return page;
|
||||
});
|
||||
|
||||
return rearrangedPages;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue