-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nv 1576 make default layout changes dependent #2711
Changes from all commits
c3c4129
34ad1f0
8c82757
de735d0
ca8c344
2cddfa4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { IsDefined, IsString, IsOptional } from 'class-validator'; | ||
import { EnvironmentWithUserCommand } from '../../../shared/commands/project.command'; | ||
import { LayoutId } from '../../types'; | ||
|
||
export class CreateDefaultLayoutChangeCommand extends EnvironmentWithUserCommand { | ||
@IsString() | ||
@IsDefined() | ||
layoutId: LayoutId; | ||
|
||
@IsString() | ||
@IsOptional() | ||
changeId?: string; | ||
|
||
@IsString() | ||
@IsOptional() | ||
parentChangeId?: string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { ChangeRepository, LayoutEntity, LayoutRepository } from '@novu/dal'; | ||
import { ChangeEntityTypeEnum } from '@novu/shared'; | ||
import { CreateChange, CreateChangeCommand } from '../../../change/usecases'; | ||
import { LayoutDto } from '../../dtos'; | ||
import { FindDeletedLayoutCommand, FindDeletedLayoutUseCase } from '../find-deleted-layout'; | ||
import { CreateDefaultLayoutChangeCommand } from './create-default-layout-change.command'; | ||
|
||
type GetChangeId = { | ||
environmentId: string; | ||
layoutId: string; | ||
}; | ||
|
||
@Injectable() | ||
export class CreateDefaultLayoutChangeUseCase { | ||
constructor( | ||
private createChange: CreateChange, | ||
private findDeletedLayout: FindDeletedLayoutUseCase, | ||
private layoutRepository: LayoutRepository, | ||
private changeRepository: ChangeRepository | ||
) {} | ||
|
||
async execute(command: CreateDefaultLayoutChangeCommand): Promise<void> { | ||
let item: LayoutEntity | LayoutDto = await this.layoutRepository.findOne({ | ||
_id: command.layoutId, | ||
_environmentId: command.environmentId, | ||
_organizationId: command.organizationId, | ||
}); | ||
|
||
const changeId = command.changeId || (await this.getChangeId(command)); | ||
|
||
if (!item) { | ||
item = await this.findDeletedLayout.execute(FindDeletedLayoutCommand.create(command)); | ||
} | ||
|
||
if (item) { | ||
await this.createChange.execute( | ||
CreateChangeCommand.create({ | ||
organizationId: command.organizationId, | ||
environmentId: command.environmentId, | ||
userId: command.userId, | ||
type: ChangeEntityTypeEnum.DEFAULT_LAYOUT, | ||
parentChangeId: command.parentChangeId, | ||
changeId, | ||
item, | ||
}) | ||
); | ||
} | ||
} | ||
|
||
private async getChangeId(command: GetChangeId) { | ||
return await this.changeRepository.getChangeId( | ||
command.environmentId, | ||
ChangeEntityTypeEnum.DEFAULT_LAYOUT, | ||
command.layoutId | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,53 @@ | ||
import { LayoutEntity, LayoutRepository } from '@novu/dal'; | ||
import { Injectable, Logger } from '@nestjs/common'; | ||
|
||
import { SetDefaultLayoutCommand } from './set-default-layout.command'; | ||
|
||
import { CreateLayoutChangeCommand, CreateLayoutChangeUseCase } from '../create-layout-change'; | ||
import { GetLayoutCommand, GetLayoutUseCase } from '../get-layout'; | ||
import { ChangeRepository, LayoutRepository } from '@novu/dal'; | ||
import { ChangeEntityTypeEnum } from '@novu/shared'; | ||
import { EnvironmentId, LayoutId, OrganizationId } from '../../types'; | ||
import { CreateDefaultLayoutChangeCommand } from '../create-default-layout-change/create-default-layout-change.command'; | ||
import { CreateDefaultLayoutChangeUseCase } from '../create-default-layout-change/create-default-layout-change.usecase'; | ||
import { GetLayoutUseCase } from '../get-layout'; | ||
import { SetDefaultLayoutCommand } from './set-default-layout.command'; | ||
|
||
@Injectable() | ||
export class SetDefaultLayoutUseCase { | ||
constructor( | ||
private getLayout: GetLayoutUseCase, | ||
private createLayoutChange: CreateLayoutChangeUseCase, | ||
private layoutRepository: LayoutRepository | ||
private createDefaultLayoutChange: CreateDefaultLayoutChangeUseCase, | ||
private layoutRepository: LayoutRepository, | ||
private changeRepository: ChangeRepository | ||
) {} | ||
|
||
async execute(command: SetDefaultLayoutCommand) { | ||
const layout = await this.getLayout.execute(command); | ||
|
||
const existingDefaultLayoutId = await this.findExistingDefaultLayoutId( | ||
layout._id, | ||
layout._id as string, | ||
command.environmentId, | ||
command.organizationId | ||
); | ||
|
||
if (!existingDefaultLayoutId) { | ||
await this.createDefaultChange(command); | ||
|
||
return; | ||
} | ||
|
||
try { | ||
if (existingDefaultLayoutId) { | ||
await this.setIsDefaultForLayout(existingDefaultLayoutId, command.environmentId, command.organizationId, false); | ||
await this.createLayoutChangeForPreviousDefault(command, existingDefaultLayoutId); | ||
} | ||
await this.setIsDefaultForLayout(existingDefaultLayoutId, command.environmentId, command.organizationId, false); | ||
|
||
const existingParentChangeId = await this.getParentChangeId(command.environmentId, existingDefaultLayoutId); | ||
const previousDefaultLayoutChangeId = await this.changeRepository.getChangeId( | ||
command.environmentId, | ||
ChangeEntityTypeEnum.DEFAULT_LAYOUT, | ||
existingDefaultLayoutId | ||
); | ||
|
||
await this.createLayoutChangeForPreviousDefault(command, existingDefaultLayoutId, previousDefaultLayoutChangeId); | ||
|
||
await this.setIsDefaultForLayout(layout._id, command.environmentId, command.organizationId, true); | ||
await this.setIsDefaultForLayout(layout._id as string, command.environmentId, command.organizationId, true); | ||
await this.createDefaultChange({ | ||
...command, | ||
parentChangeId: existingParentChangeId || previousDefaultLayoutChangeId, | ||
}); | ||
} catch (error) { | ||
Logger.error(error); | ||
// TODO: Rollback through transactions | ||
|
@@ -43,27 +56,10 @@ export class SetDefaultLayoutUseCase { | |
|
||
private async createLayoutChangeForPreviousDefault( | ||
command: SetDefaultLayoutCommand, | ||
layoutId: LayoutId | ||
): Promise<void> { | ||
const createLayoutChangeCommand = CreateLayoutChangeCommand.create({ | ||
environmentId: command.environmentId, | ||
layoutId, | ||
organizationId: command.organizationId, | ||
userId: command.userId, | ||
}); | ||
|
||
await this.createLayoutChange.execute(createLayoutChangeCommand); | ||
} | ||
|
||
private mapToEntity( | ||
domainEntity: SetDefaultLayoutCommand | ||
): Pick<LayoutEntity, '_id' | '_environmentId' | '_organizationId' | '_creatorId'> { | ||
return { | ||
_id: domainEntity.userId, | ||
_environmentId: domainEntity.environmentId, | ||
_organizationId: domainEntity.organizationId, | ||
_creatorId: domainEntity.userId, | ||
}; | ||
layoutId: LayoutId, | ||
changeId: string | ||
) { | ||
await this.createDefaultChange({ ...command, layoutId, changeId }); | ||
} | ||
|
||
private async findExistingDefaultLayoutId( | ||
|
@@ -93,4 +89,27 @@ export class SetDefaultLayoutUseCase { | |
): Promise<void> { | ||
await this.layoutRepository.updateIsDefault(layoutId, environmentId, organizationId, isDefault); | ||
} | ||
|
||
private async createDefaultChange(command: CreateDefaultLayoutChangeCommand) { | ||
const createLayoutChangeCommand = CreateDefaultLayoutChangeCommand.create({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you might be creating this command twice :) here and in line 55 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😅 Removing them |
||
environmentId: command.environmentId, | ||
layoutId: command.layoutId, | ||
organizationId: command.organizationId, | ||
userId: command.userId, | ||
changeId: command.changeId, | ||
parentChangeId: command.parentChangeId, | ||
}); | ||
|
||
await this.createDefaultLayoutChange.execute(createLayoutChangeCommand); | ||
} | ||
|
||
private async getParentChangeId(environmentId: string, layoutId: string) { | ||
const parentChangeId = await this.changeRepository.getParentId( | ||
environmentId, | ||
ChangeEntityTypeEnum.DEFAULT_LAYOUT, | ||
layoutId | ||
); | ||
|
||
return parentChangeId; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,7 +53,7 @@ export const ChangesTable = ({ | |
{ | ||
accessor: 'change', | ||
Header: 'Change', | ||
Cell: ({ type, templateName, messageType }: any) => ( | ||
Cell: ({ type, templateName, messageType, previousDefaultLayout }: any) => ( | ||
<div data-test-id="change-type"> | ||
{type === ChangeEntityTypeEnum.NOTIFICATION_TEMPLATE && ( | ||
<Text color={colorScheme === 'dark' ? colors.B40 : colors.B70}>Template Change</Text> | ||
|
@@ -70,6 +70,14 @@ export const ChangesTable = ({ | |
{type === ChangeEntityTypeEnum.LAYOUT && ( | ||
<Text color={colorScheme === 'dark' ? colors.B40 : colors.B70}>Layout Change</Text> | ||
)} | ||
{type === ChangeEntityTypeEnum.DEFAULT_LAYOUT && ( | ||
<Text color={colorScheme === 'dark' ? colors.B40 : colors.B70}>Default Layout Change</Text> | ||
)} | ||
Comment on lines
+73
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar to the line above |
||
{previousDefaultLayout && ( | ||
<Text data-test-id="previous-default-layout-content" rows={1} mt={5}> | ||
Previous Default Layout: {previousDefaultLayout} | ||
</Text> | ||
)} | ||
<Text data-test-id="change-content" rows={1} mt={5}> | ||
{templateName} | ||
{messageType ? `, ${messageType}` : null} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder what would happen if there is an update/create of layout(name,content) + setting to default. Would it create 2 changes? One for default layout change and one for layout change? If so, are we sure they are also dependent on promote?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, It will create a single(
1
) change underDefaultLayout
,This way it maintains the dependency between other layout changes too.