-
Notifications
You must be signed in to change notification settings - Fork 4.2k
feat(api-service,dashboard): layouts sync functionality fixes NV-6207 #8762
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
Conversation
✅ Deploy Preview for dashboard-v2-novu-staging canceled.
|
|
@coderabbitai summary |
✅ Actions performedSummary regeneration triggered. |
WalkthroughThis change introduces a generalized and extensible synchronization and diffing framework for both workflows and layouts across environments. It adds new base interfaces, adapters, comparators, normalizers, operations, and strategies for layouts, mirroring the existing workflow sync structure. The code also unifies resource type enums, enhances DTOs and entities with user tracking, and updates dashboard UI to restrict editing and duplication based on environment and layout origin. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Dashboard
participant API
participant SyncModule
participant WorkflowSyncStrategy
participant LayoutSyncStrategy
participant WorkflowSyncOperation
participant LayoutSyncOperation
participant RepositoryAdapter
participant ComparatorAdapter
User->>Dashboard: Initiates environment sync or diff
Dashboard->>API: Calls sync/diff endpoint
API->>SyncModule: Delegates to sync strategies
SyncModule->>WorkflowSyncStrategy: Execute workflow sync/diff
SyncModule->>LayoutSyncStrategy: Execute layout sync/diff
WorkflowSyncStrategy->>WorkflowSyncOperation: Orchestrate workflow sync
LayoutSyncStrategy->>LayoutSyncOperation: Orchestrate layout sync
WorkflowSyncOperation->>RepositoryAdapter: Fetch workflows
LayoutSyncOperation->>RepositoryAdapter: Fetch layouts
WorkflowSyncOperation->>ComparatorAdapter: Compare workflows
LayoutSyncOperation->>ComparatorAdapter: Compare layouts
WorkflowSyncOperation->>API: Return workflow sync/diff result
LayoutSyncOperation->>API: Return layout sync/diff result
API->>Dashboard: Respond with results
Estimated code review effort4 (~100 minutes) Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (65)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
| WorkflowDiffOperation, | ||
| WorkflowRepositoryService, | ||
| } from './usecases/sync-strategies/workflow'; | ||
| import { SyncModule } from './usecases/sync-strategies/sync.module'; |
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.
created the sync module where all the sync strategies and operations are defined
| import { LayoutComparator } from '../comparators/layout.comparator'; | ||
|
|
||
| @Injectable() | ||
| export class LayoutComparatorAdapter implements IBaseComparator<LayoutEntity> { |
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.
we will use this adapter pattern as the interface for actions on the resources like:
- find resources
- sync to target environment
- delete resource
- compare resources
| import { IBaseRepositoryService, IBaseComparator } from '../interfaces'; | ||
| import { capitalize } from '../../../../../shared/services/helper/helper.service'; | ||
|
|
||
| export abstract class BaseDiffOperation<T> { |
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.
the base diff operation abstract class, it is reused for both workflows and layouts
| reason?: string; | ||
| } | ||
|
|
||
| export abstract class BaseSyncOperation<T> { |
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.
base sync operation abstract class reused for both workflows and layouts
| for (const step of workflowDto.steps) { | ||
| if (step.type === StepTypeEnum.EMAIL && step.controlValues?.layoutId) { | ||
| await this.layoutSyncToEnvironmentUseCase.execute( | ||
| LayoutSyncToEnvironmentCommand.create({ | ||
| user: command.user, | ||
| layoutIdOrInternalId: step.controlValues.layoutId as string, | ||
| targetEnvironmentId: command.targetEnvironmentId, | ||
| }) | ||
| ); | ||
| } | ||
| } |
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.
for every step in the workflow when layoutId is set we should sync it first before syncing workflow
| * In the future, we can add more strategies here | ||
| */ | ||
| const strategies = [this.workflowSyncStrategy]; | ||
| const strategies = [this.workflowSyncStrategy, this.layoutSyncStrategy]; |
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 in terms of sequence and dependency, if it's better to promote layouts before workflows 🤔
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.
no need to have a specific order, as the workflow sync usecase handles layout syncing when it's used in the email step
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.
Oh I see, makes sense.
| * Or are not relevant for the comparison | ||
| */ | ||
| normalizeLayout(layout: LayoutResponseDto): INormalizedLayout { | ||
| const { _id, updatedAt, updatedBy, createdAt, slug, isDefault, origin, type, variables, ...normalizedLayout } = |
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, if we want to recognize here if the default layout is changed, do we allow changing the default? In that case I would expect the field to be there
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.
no we don't allow changing the default
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.
Got ya 💪
What changed? Why was the change needed?
Layouts Sync functionality and Editor in preview mode.
Refactored the Sync strategies and related so it is workflow agnostic and could be reused for any type of resource.
Screenshots
Screen.Recording.2025-07-22.at.10.19.57.mov
Screen.Recording.2025-07-22.at.10.18.49.mov
Screen.Recording.2025-07-22.at.10.17.51.mov
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Chores