diff --git a/src/lib/services/email-service.ts b/src/lib/services/email-service.ts index 3f3f545ef5..907dc1bc44 100644 --- a/src/lib/services/email-service.ts +++ b/src/lib/services/email-service.ts @@ -156,22 +156,92 @@ export class EmailService { flagName: string, project: string, strategyId?: string, + ) { + const conflictData = + conflictScope === 'flag' + ? { reason: 'flag archived' as const, flagName } + : { + reason: 'strategy deleted' as const, + flagName, + strategyId: strategyId ?? '', + }; + + return this.sendScheduledChangeSuspendedEmail( + recipient, + conflictData, + conflictingChangeRequestId, + changeRequests, + project, + ); + } + + async sendScheduledChangeSuspendedEmail( + recipient: string, + conflictData: + | { reason: 'flag archived'; flagName: string } + | { + reason: 'strategy deleted'; + flagName: string; + strategyId: string; + } + | { + reason: 'strategy updated'; + flagName: string; + strategyId: string; + } + | { + reason: 'segment updated'; + segment: { id: number; name: string }; + }, + conflictingChangeRequestId: number | undefined, + changeRequests: { + id: number; + scheduledAt: string; + link: string; + title?: string; + }[], + project: string, ) { if (this.configured()) { const year = new Date().getFullYear(); - const conflict = - conflictScope === 'flag' - ? `The feature flag ${flagName} in ${project} has been archived` - : `The strategy with id ${strategyId} for flag ${flagName} in ${project} has been deleted`; + const getConflictDetails = () => { + switch (conflictData.reason) { + case 'flag archived': + return { + conflictScope: 'flag', + conflict: `The feature flag ${conflictData.flagName} in ${project} has been archived`, + flagArchived: true, + flagLink: `${this.config.server.unleashUrl}/projects/${project}/archive?sort=archivedAt&search=${conflictData.flagName}`, + canBeRescheduled: false, + }; + case 'strategy deleted': + return { + conflictScope: 'strategy', + conflict: `The strategy with id ${conflictData.strategyId} for flag ${conflictData.flagName} in ${project} has been deleted`, + canBeRescheduled: false, + }; + case 'strategy updated': + return { + conflictScope: 'strategy', + conflict: `A strategy belonging to ${conflictData.flagName} (ID: ${conflictData.strategyId}) in the project ${project} has been updated, and your changes would overwrite some of the recent changes`, + canBeRescheduled: true, + }; + case 'segment updated': + return { + conflictScope: 'segment', + conflict: `Segment ${conflictData.segment.id} ("${conflictData.segment.name}") in ${project} has been updated, and your changes would overwrite some of the recent changes`, + canBeRescheduled: true, + }; + } + }; - const conflictResolution = - conflictScope === 'flag' - ? ' unless the flag is revived' - : false; - - const conflictResolutionLink = conflictResolution - ? `${this.config.server.unleashUrl}/projects/${project}/archive?sort=archivedAt&search=${flagName}` - : false; + const { + canBeRescheduled, + conflict, + conflictScope, + flagArchived = false, + flagLink = false, + } = getConflictDetails(); const conflictingChangeRequestLink = conflictingChangeRequestId ? `${this.config.server.unleashUrl}/projects/${project}/change-requests/${conflictingChangeRequestId}` @@ -183,8 +253,9 @@ export class EmailService { { conflict, conflictScope, - conflictResolution, - conflictResolutionLink, + canBeRescheduled, + flagArchived, + flagLink, conflictingChangeRequestLink, changeRequests, year, @@ -196,8 +267,10 @@ export class EmailService { { conflict, conflictScope, - conflictResolution, - conflictResolutionLink, + canBeRescheduled, + flagArchived, + flagLink, + conflictingChangeRequestLink, changeRequests, year, }, diff --git a/src/mailtemplates/scheduled-change-conflict/scheduled-change-conflict.html.mustache b/src/mailtemplates/scheduled-change-conflict/scheduled-change-conflict.html.mustache index 711844a067..76117654b6 100644 --- a/src/mailtemplates/scheduled-change-conflict/scheduled-change-conflict.html.mustache +++ b/src/mailtemplates/scheduled-change-conflict/scheduled-change-conflict.html.mustache @@ -363,10 +363,15 @@
- Conflict detected in a scheduled change+Your scheduled change requests have been suspended{{ conflict }}.-Scheduled change requests that use this {{ conflictScope }} can no longer be applied and their scheduled applications will fail{{#conflictResolution}}{{.}}{{/conflictResolution}}{{^conflictResolution}}.{{/conflictResolution}} -For you, this concerns change requests: + {{#canBeRescheduled}} +Scheduled change requests that contain updates to this {{ conflictScope }} have been suspended to prevent accidentally overwriting important configuration. If you still wish to go ahead with the changes, please reschedule the relevant change requests. If you no longer want the changes, you can reject the change request(s) instead. + {{/canBeRescheduled}} + {{^canBeRescheduled}} +Scheduled change requests that contain this {{ conflictScope }} have been suspended because they can't be applied anymore{{#flagArchived}} unless the flag is revived ({{ flagLink }}). If you revive the flag, you can then reschedule any relevant change requests and they will apply as normal. Otherwise, we{{/flagArchived}}{{^flagArchived}}. We{{/flagArchived}} recommend that you clean up by rejecting the affected change requests. + {{/canBeRescheduled}} +For you, this concerns change these requests: {{#changeRequests}}
|