Set statuses on workflows (#6792)
Add listener to keep status on workflows up to date: - version draft => statuses should contain draft - version active => statuses should contain active - version deactivated => if no version active, statuses should contain deactivated Renaming also the endpoints because it was not reflecting the full behaviour. Finally, adding a new status Archived for versions. Will be used when a version is deactivated, but is not the last published version anymore. It means this version cannot be re-activated.
This commit is contained in:
@ -0,0 +1,268 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkflowVersionStatus } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { WorkflowStatus } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import {
|
||||
WorkflowStatusesUpdateJob,
|
||||
WorkflowVersionBatchEvent,
|
||||
WorkflowVersionEventType,
|
||||
} from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
||||
|
||||
describe('WorkflowStatusesUpdate', () => {
|
||||
let job: WorkflowStatusesUpdateJob;
|
||||
|
||||
const mockWorkflowRepository = {
|
||||
findOneOrFail: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
const mockTwentyORMManager = {
|
||||
getRepository: jest.fn().mockResolvedValue(mockWorkflowRepository),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
WorkflowStatusesUpdateJob,
|
||||
{
|
||||
provide: TwentyORMManager,
|
||||
useValue: mockTwentyORMManager,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
job = await module.resolve<WorkflowStatusesUpdateJob>(
|
||||
WorkflowStatusesUpdateJob,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(job).toBeDefined();
|
||||
});
|
||||
|
||||
describe('handle', () => {
|
||||
describe('when event type is CREATE', () => {
|
||||
it('when already a draft, do not change anything', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.CREATE,
|
||||
workflowIds: ['1'],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.DRAFT],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('when no draft yet, update statuses', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.CREATE,
|
||||
workflowIds: ['1'],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
id: '1',
|
||||
statuses: [WorkflowStatus.ACTIVE],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||
{ id: '1' },
|
||||
{ statuses: [WorkflowStatus.ACTIVE, WorkflowStatus.DRAFT] },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when event type is STATUS_UPDATE', () => {
|
||||
test('when status is the same, should not do anything', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.STATUS_UPDATE,
|
||||
statusUpdates: [
|
||||
{
|
||||
workflowId: '1',
|
||||
previousStatus: WorkflowVersionStatus.ACTIVE,
|
||||
newStatus: WorkflowVersionStatus.ACTIVE,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.ACTIVE],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('when update that should be impossible, do not do anything', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.STATUS_UPDATE,
|
||||
statusUpdates: [
|
||||
{
|
||||
workflowId: '1',
|
||||
previousStatus: WorkflowVersionStatus.ACTIVE,
|
||||
newStatus: WorkflowVersionStatus.DRAFT,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.ACTIVE],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('when WorkflowVersionStatus.DEACTIVATED to WorkflowVersionStatus.ACTIVE, should activate', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.STATUS_UPDATE,
|
||||
statusUpdates: [
|
||||
{
|
||||
workflowId: '1',
|
||||
previousStatus: WorkflowVersionStatus.DEACTIVATED,
|
||||
newStatus: WorkflowVersionStatus.ACTIVE,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.DEACTIVATED],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||
{ id: '1' },
|
||||
{ statuses: [WorkflowStatus.ACTIVE] },
|
||||
);
|
||||
});
|
||||
|
||||
test('when WorkflowVersionStatus.ACTIVE to WorkflowVersionStatus.DEACTIVATED, should deactivate', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.STATUS_UPDATE,
|
||||
statusUpdates: [
|
||||
{
|
||||
workflowId: '1',
|
||||
previousStatus: WorkflowVersionStatus.ACTIVE,
|
||||
newStatus: WorkflowVersionStatus.DEACTIVATED,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.ACTIVE],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||
{ id: '1' },
|
||||
{ statuses: [WorkflowStatus.DEACTIVATED] },
|
||||
);
|
||||
});
|
||||
|
||||
test('when WorkflowVersionStatus.DRAFT to WorkflowVersionStatus.ACTIVE, should activate', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.STATUS_UPDATE,
|
||||
statusUpdates: [
|
||||
{
|
||||
workflowId: '1',
|
||||
previousStatus: WorkflowVersionStatus.DRAFT,
|
||||
newStatus: WorkflowVersionStatus.ACTIVE,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.DRAFT],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||
{ id: '1' },
|
||||
{ statuses: [WorkflowStatus.ACTIVE] },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when event type is DELETE', () => {
|
||||
test('when status is not draft, should not do anything', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.DELETE,
|
||||
workflowIds: ['1'],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.ACTIVE],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('when status is draft, should delete', async () => {
|
||||
const event: WorkflowVersionBatchEvent = {
|
||||
workspaceId: '1',
|
||||
type: WorkflowVersionEventType.DELETE,
|
||||
workflowIds: ['1'],
|
||||
};
|
||||
|
||||
const mockWorkflow = {
|
||||
statuses: [WorkflowStatus.DRAFT],
|
||||
};
|
||||
|
||||
mockWorkflowRepository.findOneOrFail.mockResolvedValue(mockWorkflow);
|
||||
|
||||
await job.handle(event);
|
||||
|
||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||
{ id: '1' },
|
||||
{ statuses: [] },
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,201 @@
|
||||
import { Scope } from '@nestjs/common';
|
||||
|
||||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkflowVersionStatus } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import { getStatusCombinationFromArray } from 'src/modules/workflow/workflow-status/utils/get-status-combination-from-array.util';
|
||||
import { getStatusCombinationFromUpdate } from 'src/modules/workflow/workflow-status/utils/get-status-combination-from-update.util';
|
||||
import { getWorkflowStatusesFromCombination } from 'src/modules/workflow/workflow-status/utils/get-statuses-from-combination.util';
|
||||
|
||||
export enum WorkflowVersionEventType {
|
||||
CREATE = 'CREATE',
|
||||
STATUS_UPDATE = 'STATUS_UPDATE',
|
||||
DELETE = 'DELETE',
|
||||
}
|
||||
|
||||
export type WorkflowVersionBatchEvent = {
|
||||
workspaceId: string;
|
||||
} & (
|
||||
| WorkflowVersionBatchCreateEvent
|
||||
| WorkflowVersionBatchStatusUpdate
|
||||
| WorkflowVersionBatchDelete
|
||||
);
|
||||
|
||||
export type WorkflowVersionBatchCreateEvent = {
|
||||
type: WorkflowVersionEventType.CREATE;
|
||||
} & {
|
||||
workflowIds: string[];
|
||||
};
|
||||
|
||||
export type WorkflowVersionStatusUpdate = {
|
||||
workflowId: string;
|
||||
previousStatus: WorkflowVersionStatus;
|
||||
newStatus: WorkflowVersionStatus;
|
||||
};
|
||||
|
||||
export type WorkflowVersionBatchStatusUpdate = {
|
||||
type: WorkflowVersionEventType.STATUS_UPDATE;
|
||||
} & {
|
||||
statusUpdates: WorkflowVersionStatusUpdate[];
|
||||
};
|
||||
|
||||
export type WorkflowVersionBatchDelete = {
|
||||
type: WorkflowVersionEventType.DELETE;
|
||||
} & { workflowIds: string[] };
|
||||
|
||||
@Processor({ queueName: MessageQueue.workflowQueue, scope: Scope.REQUEST })
|
||||
export class WorkflowStatusesUpdateJob {
|
||||
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
||||
|
||||
@Process(WorkflowStatusesUpdateJob.name)
|
||||
async handle(event: WorkflowVersionBatchEvent): Promise<void> {
|
||||
switch (event.type) {
|
||||
case WorkflowVersionEventType.CREATE:
|
||||
await Promise.all(
|
||||
event.workflowIds.map((workflowId) =>
|
||||
this.handleWorkflowVersionCreated(workflowId),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case WorkflowVersionEventType.STATUS_UPDATE:
|
||||
await Promise.all(
|
||||
event.statusUpdates.map((statusUpdate) =>
|
||||
this.handleWorkflowVersionStatusUpdated(statusUpdate),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case WorkflowVersionEventType.DELETE:
|
||||
await Promise.all(
|
||||
event.workflowIds.map((workflowId) =>
|
||||
this.handleWorkflowVersionDeleted(workflowId),
|
||||
),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async handleWorkflowVersionCreated(
|
||||
workflowId: string,
|
||||
): Promise<void> {
|
||||
const workflowRepository =
|
||||
await this.twentyORMManager.getRepository<WorkflowWorkspaceEntity>(
|
||||
'workflow',
|
||||
);
|
||||
|
||||
const workflow = await workflowRepository.findOneOrFail({
|
||||
where: {
|
||||
id: workflowId,
|
||||
},
|
||||
});
|
||||
|
||||
const currentWorkflowStatusCombination = getStatusCombinationFromArray(
|
||||
workflow.statuses || [],
|
||||
);
|
||||
|
||||
const newWorkflowStatusCombination = getStatusCombinationFromUpdate(
|
||||
currentWorkflowStatusCombination,
|
||||
undefined,
|
||||
WorkflowVersionStatus.DRAFT,
|
||||
);
|
||||
|
||||
if (newWorkflowStatusCombination === currentWorkflowStatusCombination) {
|
||||
return;
|
||||
}
|
||||
|
||||
await workflowRepository.update(
|
||||
{
|
||||
id: workflow.id,
|
||||
},
|
||||
{
|
||||
statuses: getWorkflowStatusesFromCombination(
|
||||
newWorkflowStatusCombination,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private async handleWorkflowVersionStatusUpdated(
|
||||
statusUpdate: WorkflowVersionStatusUpdate,
|
||||
): Promise<void> {
|
||||
const workflowRepository =
|
||||
await this.twentyORMManager.getRepository<WorkflowWorkspaceEntity>(
|
||||
'workflow',
|
||||
);
|
||||
|
||||
const workflow = await workflowRepository.findOneOrFail({
|
||||
where: {
|
||||
id: statusUpdate.workflowId,
|
||||
},
|
||||
});
|
||||
|
||||
const currentWorkflowStatusCombination = getStatusCombinationFromArray(
|
||||
workflow.statuses || [],
|
||||
);
|
||||
|
||||
const newWorkflowStatusCombination = getStatusCombinationFromUpdate(
|
||||
currentWorkflowStatusCombination,
|
||||
statusUpdate.previousStatus,
|
||||
statusUpdate.newStatus,
|
||||
);
|
||||
|
||||
if (newWorkflowStatusCombination === currentWorkflowStatusCombination) {
|
||||
return;
|
||||
}
|
||||
|
||||
await workflowRepository.update(
|
||||
{
|
||||
id: statusUpdate.workflowId,
|
||||
},
|
||||
{
|
||||
statuses: getWorkflowStatusesFromCombination(
|
||||
newWorkflowStatusCombination,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private async handleWorkflowVersionDeleted(
|
||||
workflowId: string,
|
||||
): Promise<void> {
|
||||
const workflowRepository =
|
||||
await this.twentyORMManager.getRepository<WorkflowWorkspaceEntity>(
|
||||
'workflow',
|
||||
);
|
||||
|
||||
const workflow = await workflowRepository.findOneOrFail({
|
||||
where: {
|
||||
id: workflowId,
|
||||
},
|
||||
});
|
||||
|
||||
const currentWorkflowStatusCombination = getStatusCombinationFromArray(
|
||||
workflow.statuses || [],
|
||||
);
|
||||
|
||||
const newWorkflowStatusCombination = getStatusCombinationFromUpdate(
|
||||
currentWorkflowStatusCombination,
|
||||
WorkflowVersionStatus.DRAFT,
|
||||
undefined,
|
||||
);
|
||||
|
||||
if (newWorkflowStatusCombination === currentWorkflowStatusCombination) {
|
||||
return;
|
||||
}
|
||||
|
||||
await workflowRepository.update(
|
||||
{
|
||||
id: workflowId,
|
||||
},
|
||||
{
|
||||
statuses: getWorkflowStatusesFromCombination(
|
||||
newWorkflowStatusCombination,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { OnEvent } from '@nestjs/event-emitter';
|
||||
|
||||
import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event';
|
||||
import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event';
|
||||
import { InjectMessageQueue } from 'src/engine/integrations/message-queue/decorators/message-queue.decorator';
|
||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
||||
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/workspace-event.type';
|
||||
import {
|
||||
WorkflowVersionStatus,
|
||||
WorkflowVersionWorkspaceEntity,
|
||||
} from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import {
|
||||
WorkflowStatusesUpdateJob,
|
||||
WorkflowVersionBatchEvent,
|
||||
WorkflowVersionEventType,
|
||||
WorkflowVersionStatusUpdate,
|
||||
} from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
||||
|
||||
@Injectable()
|
||||
export class WorkflowVersionStatusListener {
|
||||
constructor(
|
||||
@InjectMessageQueue(MessageQueue.workflowQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
) {}
|
||||
|
||||
@OnEvent('workflowVersion.created')
|
||||
async handleWorkflowVersionCreated(
|
||||
payload: WorkspaceEventBatch<
|
||||
ObjectRecordCreateEvent<WorkflowVersionWorkspaceEntity>
|
||||
>,
|
||||
): Promise<void> {
|
||||
const workflowIds = payload.events
|
||||
.filter(
|
||||
(event) =>
|
||||
!event.properties.after.status ||
|
||||
event.properties.after.status === WorkflowVersionStatus.DRAFT,
|
||||
)
|
||||
.map((event) => event.properties.after.workflowId);
|
||||
|
||||
if (workflowIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.messageQueueService.add<WorkflowVersionBatchEvent>(
|
||||
WorkflowStatusesUpdateJob.name,
|
||||
{
|
||||
type: WorkflowVersionEventType.CREATE,
|
||||
workspaceId: payload.workspaceId,
|
||||
workflowIds,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@OnEvent('workflowVersion.statusUpdated')
|
||||
async handleWorkflowVersionUpdated(
|
||||
payload: WorkspaceEventBatch<WorkflowVersionStatusUpdate>,
|
||||
): Promise<void> {
|
||||
await this.messageQueueService.add<WorkflowVersionBatchEvent>(
|
||||
WorkflowStatusesUpdateJob.name,
|
||||
{
|
||||
type: WorkflowVersionEventType.STATUS_UPDATE,
|
||||
workspaceId: payload.workspaceId,
|
||||
statusUpdates: payload.events,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@OnEvent('workflowVersion.deleted')
|
||||
async handleWorkflowVersionDeleted(
|
||||
payload: WorkspaceEventBatch<
|
||||
ObjectRecordDeleteEvent<WorkflowVersionWorkspaceEntity>
|
||||
>,
|
||||
): Promise<void> {
|
||||
const workflowIds = payload.events
|
||||
.filter(
|
||||
(event) =>
|
||||
event.properties.before.status === WorkflowVersionStatus.DRAFT,
|
||||
)
|
||||
.map((event) => event.properties.before.workflowId);
|
||||
|
||||
if (workflowIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.messageQueueService.add<WorkflowVersionBatchEvent>(
|
||||
WorkflowStatusesUpdateJob.name,
|
||||
{
|
||||
type: WorkflowVersionEventType.DELETE,
|
||||
workspaceId: payload.workspaceId,
|
||||
workflowIds,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
import isEqual from 'lodash.isequal';
|
||||
|
||||
import { WorkflowStatus } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import {
|
||||
ACTIVE_AND_DRAFT_STATUSES,
|
||||
ACTIVE_STATUSES,
|
||||
DEACTIVATED_AND_DRAFT_STATUSES,
|
||||
DEACTIVATED_STATUSES,
|
||||
DRAFT_STATUSES,
|
||||
} from 'src/modules/workflow/workflow-status/workflow-status.constants';
|
||||
import { WorkflowStatusCombination } from 'src/modules/workflow/workflow-status/workflow-status.enums';
|
||||
|
||||
export const getStatusCombinationFromArray = (
|
||||
statuses: WorkflowStatus[],
|
||||
): WorkflowStatusCombination => {
|
||||
if (isEqual(statuses, ACTIVE_AND_DRAFT_STATUSES)) {
|
||||
return WorkflowStatusCombination.ACTIVE_AND_DRAFT;
|
||||
}
|
||||
|
||||
if (isEqual(statuses, ACTIVE_STATUSES)) {
|
||||
return WorkflowStatusCombination.ACTIVE;
|
||||
}
|
||||
|
||||
if (isEqual(statuses, DEACTIVATED_AND_DRAFT_STATUSES)) {
|
||||
return WorkflowStatusCombination.DEACTIVATED_AND_DRAFT;
|
||||
}
|
||||
|
||||
if (isEqual(statuses, DEACTIVATED_STATUSES)) {
|
||||
return WorkflowStatusCombination.DEACTIVATED;
|
||||
}
|
||||
|
||||
if (isEqual(statuses, DRAFT_STATUSES)) {
|
||||
return WorkflowStatusCombination.DRAFT;
|
||||
}
|
||||
|
||||
return WorkflowStatusCombination.NO_STATUSES;
|
||||
};
|
||||
@ -0,0 +1,75 @@
|
||||
import { WorkflowVersionStatus } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { WorkflowStatusCombination } from 'src/modules/workflow/workflow-status/workflow-status.enums';
|
||||
|
||||
export const getStatusCombinationFromUpdate = (
|
||||
previousCombination: WorkflowStatusCombination,
|
||||
statusToRemove?: WorkflowVersionStatus,
|
||||
statusToAdd?: WorkflowVersionStatus,
|
||||
): WorkflowStatusCombination => {
|
||||
switch (previousCombination) {
|
||||
case WorkflowStatusCombination.ACTIVE_AND_DRAFT:
|
||||
if (
|
||||
statusToAdd === WorkflowVersionStatus.ACTIVE &&
|
||||
statusToRemove === WorkflowVersionStatus.DRAFT
|
||||
) {
|
||||
return WorkflowStatusCombination.ACTIVE;
|
||||
}
|
||||
if (statusToRemove === WorkflowVersionStatus.DRAFT) {
|
||||
return WorkflowStatusCombination.ACTIVE;
|
||||
}
|
||||
break;
|
||||
case WorkflowStatusCombination.DEACTIVATED_AND_DRAFT:
|
||||
if (
|
||||
statusToRemove === WorkflowVersionStatus.DRAFT &&
|
||||
statusToAdd === WorkflowVersionStatus.ACTIVE
|
||||
) {
|
||||
return WorkflowStatusCombination.ACTIVE;
|
||||
}
|
||||
if (statusToRemove === WorkflowVersionStatus.DRAFT) {
|
||||
return WorkflowStatusCombination.DEACTIVATED;
|
||||
}
|
||||
break;
|
||||
case WorkflowStatusCombination.ACTIVE:
|
||||
if (
|
||||
statusToRemove === WorkflowVersionStatus.ACTIVE &&
|
||||
statusToAdd === WorkflowVersionStatus.DEACTIVATED
|
||||
) {
|
||||
return WorkflowStatusCombination.DEACTIVATED;
|
||||
}
|
||||
if (!statusToRemove && statusToAdd === WorkflowVersionStatus.DRAFT) {
|
||||
return WorkflowStatusCombination.ACTIVE_AND_DRAFT;
|
||||
}
|
||||
break;
|
||||
case WorkflowStatusCombination.DEACTIVATED:
|
||||
if (
|
||||
statusToRemove === WorkflowVersionStatus.DEACTIVATED &&
|
||||
statusToAdd === WorkflowVersionStatus.ACTIVE
|
||||
) {
|
||||
return WorkflowStatusCombination.ACTIVE;
|
||||
}
|
||||
if (!statusToRemove && statusToAdd === WorkflowVersionStatus.DRAFT) {
|
||||
return WorkflowStatusCombination.DEACTIVATED_AND_DRAFT;
|
||||
}
|
||||
break;
|
||||
case WorkflowStatusCombination.DRAFT:
|
||||
if (
|
||||
statusToRemove === WorkflowVersionStatus.DRAFT &&
|
||||
statusToAdd === WorkflowVersionStatus.ACTIVE
|
||||
) {
|
||||
return WorkflowStatusCombination.ACTIVE;
|
||||
}
|
||||
if (statusToRemove === WorkflowVersionStatus.DRAFT) {
|
||||
return WorkflowStatusCombination.NO_STATUSES;
|
||||
}
|
||||
break;
|
||||
case WorkflowStatusCombination.NO_STATUSES:
|
||||
if (statusToAdd === WorkflowVersionStatus.DRAFT) {
|
||||
return WorkflowStatusCombination.DRAFT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return previousCombination;
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
import { WorkflowStatus } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import {
|
||||
ACTIVE_AND_DRAFT_STATUSES,
|
||||
ACTIVE_STATUSES,
|
||||
DEACTIVATED_AND_DRAFT_STATUSES,
|
||||
DEACTIVATED_STATUSES,
|
||||
DRAFT_STATUSES,
|
||||
NO_STATUSES,
|
||||
} from 'src/modules/workflow/workflow-status/workflow-status.constants';
|
||||
import { WorkflowStatusCombination } from 'src/modules/workflow/workflow-status/workflow-status.enums';
|
||||
|
||||
export const getWorkflowStatusesFromCombination = (
|
||||
combination: WorkflowStatusCombination,
|
||||
): WorkflowStatus[] => {
|
||||
switch (combination) {
|
||||
case WorkflowStatusCombination.ACTIVE:
|
||||
return ACTIVE_STATUSES;
|
||||
case WorkflowStatusCombination.DRAFT:
|
||||
return DRAFT_STATUSES;
|
||||
case WorkflowStatusCombination.DEACTIVATED:
|
||||
return DEACTIVATED_STATUSES;
|
||||
case WorkflowStatusCombination.ACTIVE_AND_DRAFT:
|
||||
return ACTIVE_AND_DRAFT_STATUSES;
|
||||
case WorkflowStatusCombination.DEACTIVATED_AND_DRAFT:
|
||||
return DEACTIVATED_AND_DRAFT_STATUSES;
|
||||
case WorkflowStatusCombination.NO_STATUSES:
|
||||
return NO_STATUSES;
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import { WorkflowStatus } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
|
||||
export const ACTIVE_AND_DRAFT_STATUSES = [
|
||||
WorkflowStatus.ACTIVE,
|
||||
WorkflowStatus.DRAFT,
|
||||
];
|
||||
|
||||
export const DEACTIVATED_AND_DRAFT_STATUSES = [
|
||||
WorkflowStatus.DEACTIVATED,
|
||||
WorkflowStatus.DRAFT,
|
||||
];
|
||||
|
||||
export const ACTIVE_STATUSES = [WorkflowStatus.ACTIVE];
|
||||
|
||||
export const DEACTIVATED_STATUSES = [WorkflowStatus.DEACTIVATED];
|
||||
|
||||
export const DRAFT_STATUSES = [WorkflowStatus.DRAFT];
|
||||
|
||||
export const NO_STATUSES = [];
|
||||
@ -0,0 +1,8 @@
|
||||
export enum WorkflowStatusCombination {
|
||||
ACTIVE = 'ACTIVE',
|
||||
DRAFT = 'DRAFT',
|
||||
DEACTIVATED = 'DEACTIVATED',
|
||||
ACTIVE_AND_DRAFT = 'ACTIVE_AND_DRAFT',
|
||||
DEACTIVATED_AND_DRAFT = 'DEACTIVATED_AND_DRAFT',
|
||||
NO_STATUSES = 'NO_STATUSES',
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkflowStatusesUpdateJob } from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
||||
import { WorkflowVersionStatusListener } from 'src/modules/workflow/workflow-status/listeners/workflow-version-status.listener';
|
||||
|
||||
@Module({
|
||||
providers: [WorkflowStatusesUpdateJob, WorkflowVersionStatusListener],
|
||||
})
|
||||
export class WorkflowStatusModule {}
|
||||
Reference in New Issue
Block a user