diff --git a/packages/n8n-node/nodes/Probo/Probo.node.ts b/packages/n8n-node/nodes/Probo/Probo.node.ts index ce5882af7..2f99db160 100644 --- a/packages/n8n-node/nodes/Probo/Probo.node.ts +++ b/packages/n8n-node/nodes/Probo/Probo.node.ts @@ -107,6 +107,11 @@ export class Probo implements INodeType { value: 'people', description: 'Manage people', }, + { + name: 'Risk', + value: 'risk', + description: 'Manage risks', + }, { name: 'Vendor', value: 'vendor', diff --git a/packages/n8n-node/nodes/Probo/actions/index.ts b/packages/n8n-node/nodes/Probo/actions/index.ts index 14aaf0a7d..0a619ddbe 100644 --- a/packages/n8n-node/nodes/Probo/actions/index.ts +++ b/packages/n8n-node/nodes/Probo/actions/index.ts @@ -8,6 +8,7 @@ import * as measure from './measure'; import * as meeting from './meeting'; import * as organization from './organization'; import * as people from './people'; +import * as risk from './risk'; import * as vendor from './vendor'; export interface ResourceModule { @@ -30,6 +31,7 @@ export const resources: Record = { meeting: meeting as ResourceModule, organization: organization as ResourceModule, people: people as ResourceModule, + risk: risk as ResourceModule, vendor: vendor as ResourceModule, }; diff --git a/packages/n8n-node/nodes/Probo/actions/risk/create.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/create.operation.ts new file mode 100644 index 000000000..a8bfea31b --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/create.operation.ts @@ -0,0 +1,238 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Organization ID', + name: 'organizationId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['create'], + }, + }, + default: '', + description: 'The ID of the organization', + required: true, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['create'], + }, + }, + default: '', + description: 'The name of the risk', + required: true, + }, + { + displayName: 'Category', + name: 'category', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['create'], + }, + }, + default: '', + description: 'The category of the risk', + required: true, + }, + { + displayName: 'Treatment', + name: 'treatment', + type: 'options', + displayOptions: { + show: { + resource: ['risk'], + operation: ['create'], + }, + }, + options: [ + { + name: 'Mitigated', + value: 'MITIGATED', + }, + { + name: 'Accepted', + value: 'ACCEPTED', + }, + { + name: 'Avoided', + value: 'AVOIDED', + }, + { + name: 'Transferred', + value: 'TRANSFERRED', + }, + ], + default: 'MITIGATED', + description: 'The treatment strategy for the risk', + required: true, + }, + { + displayName: 'Inherent Likelihood', + name: 'inherentLikelihood', + type: 'number', + displayOptions: { + show: { + resource: ['risk'], + operation: ['create'], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The inherent likelihood of the risk (1-5)', + required: true, + }, + { + displayName: 'Inherent Impact', + name: 'inherentImpact', + type: 'number', + displayOptions: { + show: { + resource: ['risk'], + operation: ['create'], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The inherent impact of the risk (1-5)', + required: true, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: ['risk'], + operation: ['create'], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: 'The description of the risk', + }, + { + displayName: 'Note', + name: 'note', + type: 'string', + default: '', + description: 'Additional notes about the risk', + }, + { + displayName: 'Owner ID', + name: 'ownerId', + type: 'string', + default: '', + description: 'The ID of the person who owns this risk', + }, + { + displayName: 'Residual Impact', + name: 'residualImpact', + type: 'number', + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The residual impact of the risk (1-5)', + }, + { + displayName: 'Residual Likelihood', + name: 'residualLikelihood', + type: 'number', + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The residual likelihood of the risk (1-5)', + }, + ], + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const organizationId = this.getNodeParameter('organizationId', itemIndex) as string; + const name = this.getNodeParameter('name', itemIndex) as string; + const category = this.getNodeParameter('category', itemIndex) as string; + const treatment = this.getNodeParameter('treatment', itemIndex) as string; + const inherentLikelihood = this.getNodeParameter('inherentLikelihood', itemIndex) as number; + const inherentImpact = this.getNodeParameter('inherentImpact', itemIndex) as number; + const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {}) as { + description?: string; + ownerId?: string; + residualLikelihood?: number; + residualImpact?: number; + note?: string; + }; + + const query = ` + mutation CreateRisk($input: CreateRiskInput!) { + createRisk(input: $input) { + riskEdge { + node { + id + name + description + category + treatment + inherentLikelihood + inherentImpact + inherentRiskScore + residualLikelihood + residualImpact + residualRiskScore + note + createdAt + updatedAt + } + } + } + } + `; + + const input: Record = { + organizationId, + name, + category, + treatment, + inherentLikelihood, + inherentImpact, + }; + if (additionalFields.description) input.description = additionalFields.description; + if (additionalFields.ownerId) input.ownerId = additionalFields.ownerId; + if (additionalFields.residualLikelihood !== undefined) input.residualLikelihood = additionalFields.residualLikelihood; + if (additionalFields.residualImpact !== undefined) input.residualImpact = additionalFields.residualImpact; + if (additionalFields.note) input.note = additionalFields.note; + + const responseData = await proboApiRequest.call(this, query, { input }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/delete.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/delete.operation.ts new file mode 100644 index 000000000..c6857de2e --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/delete.operation.ts @@ -0,0 +1,41 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['delete'], + }, + }, + default: '', + description: 'The ID of the risk to delete', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + + const query = ` + mutation DeleteRisk($input: DeleteRiskInput!) { + deleteRisk(input: $input) { + deletedRiskId + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { riskId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/get.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/get.operation.ts new file mode 100644 index 000000000..01c53dcf8 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/get.operation.ts @@ -0,0 +1,60 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['get'], + }, + }, + default: '', + description: 'The ID of the risk', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + + const query = ` + query GetRisk($riskId: ID!) { + node(id: $riskId) { + ... on Risk { + id + name + description + category + treatment + inherentLikelihood + inherentImpact + inherentRiskScore + residualLikelihood + residualImpact + residualRiskScore + note + createdAt + updatedAt + } + } + } + `; + + const variables = { + riskId, + }; + + const responseData = await proboApiRequest.call(this, query, variables); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/getAll.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/getAll.operation.ts new file mode 100644 index 000000000..03f3afb2f --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/getAll.operation.ts @@ -0,0 +1,109 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData, IDataObject } from 'n8n-workflow'; +import { proboApiRequestAllItems } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Organization ID', + name: 'organizationId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['getAll'], + }, + }, + default: '', + description: 'The ID of the organization', + required: true, + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: ['risk'], + operation: ['getAll'], + }, + }, + default: false, + description: 'Whether to return all results or only up to a given limit', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: ['risk'], + operation: ['getAll'], + returnAll: [false], + }, + }, + typeOptions: { + minValue: 1, + }, + default: 50, + description: 'Max number of results to return', + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const organizationId = this.getNodeParameter('organizationId', itemIndex) as string; + const returnAll = this.getNodeParameter('returnAll', itemIndex) as boolean; + const limit = this.getNodeParameter('limit', itemIndex, 50) as number; + + const query = ` + query GetRisks($organizationId: ID!, $first: Int, $after: CursorKey) { + node(id: $organizationId) { + ... on Organization { + risks(first: $first, after: $after) { + edges { + node { + id + name + description + category + treatment + inherentLikelihood + inherentImpact + inherentRiskScore + residualLikelihood + residualImpact + residualRiskScore + note + createdAt + updatedAt + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + } + } + `; + + const risks = await proboApiRequestAllItems.call( + this, + query, + { organizationId }, + (response) => { + const data = response?.data as IDataObject | undefined; + const node = data?.node as IDataObject | undefined; + return node?.risks as IDataObject | undefined; + }, + returnAll, + limit, + ); + + return { + json: { risks }, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/index.ts b/packages/n8n-node/nodes/Probo/actions/risk/index.ts new file mode 100644 index 000000000..3b1ca0085 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/index.ts @@ -0,0 +1,120 @@ +import type { INodeProperties } from 'n8n-workflow'; +import * as createOp from './create.operation'; +import * as updateOp from './update.operation'; +import * as deleteOp from './delete.operation'; +import * as getOp from './get.operation'; +import * as getAllOp from './getAll.operation'; +import * as linkMeasureOp from './linkMeasure.operation'; +import * as unlinkMeasureOp from './unlinkMeasure.operation'; +import * as linkDocumentOp from './linkDocument.operation'; +import * as unlinkDocumentOp from './unlinkDocument.operation'; +import * as linkObligationOp from './linkObligation.operation'; +import * as unlinkObligationOp from './unlinkObligation.operation'; + +export const description: INodeProperties[] = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { + show: { + resource: ['risk'], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a new risk', + action: 'Create a risk', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a risk', + action: 'Delete a risk', + }, + { + name: 'Get', + value: 'get', + description: 'Get a risk', + action: 'Get a risk', + }, + { + name: 'Get Many', + value: 'getAll', + description: 'Get many risks', + action: 'Get many risks', + }, + { + name: 'Link Document', + value: 'linkDocument', + description: 'Link a document to a risk', + action: 'Link a document to a risk', + }, + { + name: 'Link Measure', + value: 'linkMeasure', + description: 'Link a measure to a risk', + action: 'Link a measure to a risk', + }, + { + name: 'Link Obligation', + value: 'linkObligation', + description: 'Link an obligation to a risk', + action: 'Link an obligation to a risk', + }, + { + name: 'Unlink Document', + value: 'unlinkDocument', + description: 'Unlink a document from a risk', + action: 'Unlink a document from a risk', + }, + { + name: 'Unlink Measure', + value: 'unlinkMeasure', + description: 'Unlink a measure from a risk', + action: 'Unlink a measure from a risk', + }, + { + name: 'Unlink Obligation', + value: 'unlinkObligation', + description: 'Unlink an obligation from a risk', + action: 'Unlink an obligation from a risk', + }, + { + name: 'Update', + value: 'update', + description: 'Update an existing risk', + action: 'Update a risk', + }, + ], + default: 'create', + }, + ...createOp.description, + ...updateOp.description, + ...deleteOp.description, + ...getOp.description, + ...getAllOp.description, + ...linkMeasureOp.description, + ...unlinkMeasureOp.description, + ...linkDocumentOp.description, + ...unlinkDocumentOp.description, + ...linkObligationOp.description, + ...unlinkObligationOp.description, +]; + +export { + createOp as create, + updateOp as update, + deleteOp as delete, + getOp as get, + getAllOp as getAll, + linkMeasureOp as linkMeasure, + unlinkMeasureOp as unlinkMeasure, + linkDocumentOp as linkDocument, + unlinkDocumentOp as unlinkDocument, + linkObligationOp as linkObligation, + unlinkObligationOp as unlinkObligation, +}; diff --git a/packages/n8n-node/nodes/Probo/actions/risk/linkDocument.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/linkDocument.operation.ts new file mode 100644 index 000000000..a6ba93d19 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/linkDocument.operation.ts @@ -0,0 +1,67 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['linkDocument'], + }, + }, + default: '', + description: 'The ID of the risk', + required: true, + }, + { + displayName: 'Document ID', + name: 'documentId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['linkDocument'], + }, + }, + default: '', + description: 'The ID of the document to link', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + const documentId = this.getNodeParameter('documentId', itemIndex) as string; + + const query = ` + mutation CreateRiskDocumentMapping($input: CreateRiskDocumentMappingInput!) { + createRiskDocumentMapping(input: $input) { + riskEdge { + node { + id + name + } + } + documentEdge { + node { + id + title + } + } + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { riskId, documentId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/linkMeasure.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/linkMeasure.operation.ts new file mode 100644 index 000000000..08b3b3737 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/linkMeasure.operation.ts @@ -0,0 +1,67 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['linkMeasure'], + }, + }, + default: '', + description: 'The ID of the risk', + required: true, + }, + { + displayName: 'Measure ID', + name: 'measureId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['linkMeasure'], + }, + }, + default: '', + description: 'The ID of the measure to link', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + const measureId = this.getNodeParameter('measureId', itemIndex) as string; + + const query = ` + mutation CreateRiskMeasureMapping($input: CreateRiskMeasureMappingInput!) { + createRiskMeasureMapping(input: $input) { + riskEdge { + node { + id + name + } + } + measureEdge { + node { + id + name + } + } + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { riskId, measureId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/linkObligation.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/linkObligation.operation.ts new file mode 100644 index 000000000..bff2b1f9d --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/linkObligation.operation.ts @@ -0,0 +1,67 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['linkObligation'], + }, + }, + default: '', + description: 'The ID of the risk', + required: true, + }, + { + displayName: 'Obligation ID', + name: 'obligationId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['linkObligation'], + }, + }, + default: '', + description: 'The ID of the obligation to link', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + const obligationId = this.getNodeParameter('obligationId', itemIndex) as string; + + const query = ` + mutation CreateRiskObligationMapping($input: CreateRiskObligationMappingInput!) { + createRiskObligationMapping(input: $input) { + riskEdge { + node { + id + name + } + } + obligationEdge { + node { + id + name + } + } + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { riskId, obligationId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/unlinkDocument.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/unlinkDocument.operation.ts new file mode 100644 index 000000000..49aaf1d36 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/unlinkDocument.operation.ts @@ -0,0 +1,57 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['unlinkDocument'], + }, + }, + default: '', + description: 'The ID of the risk', + required: true, + }, + { + displayName: 'Document ID', + name: 'documentId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['unlinkDocument'], + }, + }, + default: '', + description: 'The ID of the document to unlink', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + const documentId = this.getNodeParameter('documentId', itemIndex) as string; + + const query = ` + mutation DeleteRiskDocumentMapping($input: DeleteRiskDocumentMappingInput!) { + deleteRiskDocumentMapping(input: $input) { + deletedRiskId + deletedDocumentId + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { riskId, documentId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/unlinkMeasure.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/unlinkMeasure.operation.ts new file mode 100644 index 000000000..78c88d8b7 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/unlinkMeasure.operation.ts @@ -0,0 +1,57 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['unlinkMeasure'], + }, + }, + default: '', + description: 'The ID of the risk', + required: true, + }, + { + displayName: 'Measure ID', + name: 'measureId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['unlinkMeasure'], + }, + }, + default: '', + description: 'The ID of the measure to unlink', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + const measureId = this.getNodeParameter('measureId', itemIndex) as string; + + const query = ` + mutation DeleteRiskMeasureMapping($input: DeleteRiskMeasureMappingInput!) { + deleteRiskMeasureMapping(input: $input) { + deletedRiskId + deletedMeasureId + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { riskId, measureId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/unlinkObligation.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/unlinkObligation.operation.ts new file mode 100644 index 000000000..06085183d --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/unlinkObligation.operation.ts @@ -0,0 +1,57 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['unlinkObligation'], + }, + }, + default: '', + description: 'The ID of the risk', + required: true, + }, + { + displayName: 'Obligation ID', + name: 'obligationId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['unlinkObligation'], + }, + }, + default: '', + description: 'The ID of the obligation to unlink', + required: true, + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + const obligationId = this.getNodeParameter('obligationId', itemIndex) as string; + + const query = ` + mutation DeleteRiskObligationMapping($input: DeleteRiskObligationMappingInput!) { + deleteRiskObligationMapping(input: $input) { + deletedRiskId + deletedObligationId + } + } + `; + + const responseData = await proboApiRequest.call(this, query, { input: { riskId, obligationId } }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +} diff --git a/packages/n8n-node/nodes/Probo/actions/risk/update.operation.ts b/packages/n8n-node/nodes/Probo/actions/risk/update.operation.ts new file mode 100644 index 000000000..0d7a635a8 --- /dev/null +++ b/packages/n8n-node/nodes/Probo/actions/risk/update.operation.ts @@ -0,0 +1,217 @@ +import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; +import { proboApiRequest } from '../../GenericFunctions'; + +export const description: INodeProperties[] = [ + { + displayName: 'Risk ID', + name: 'riskId', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['update'], + }, + }, + default: '', + description: 'The ID of the risk to update', + required: true, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['update'], + }, + }, + default: '', + description: 'The name of the risk', + }, + { + displayName: 'Category', + name: 'category', + type: 'string', + displayOptions: { + show: { + resource: ['risk'], + operation: ['update'], + }, + }, + default: '', + description: 'The category of the risk', + }, + { + displayName: 'Treatment', + name: 'treatment', + type: 'options', + displayOptions: { + show: { + resource: ['risk'], + operation: ['update'], + }, + }, + options: [ + { + name: 'Mitigated', + value: 'MITIGATED', + }, + { + name: 'Accepted', + value: 'ACCEPTED', + }, + { + name: 'Avoided', + value: 'AVOIDED', + }, + { + name: 'Transferred', + value: 'TRANSFERRED', + }, + ], + default: 'MITIGATED', + description: 'The treatment strategy for the risk', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: ['risk'], + operation: ['update'], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: 'The description of the risk', + }, + { + displayName: 'Inherent Impact', + name: 'inherentImpact', + type: 'number', + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The inherent impact of the risk (1-5)', + }, + { + displayName: 'Inherent Likelihood', + name: 'inherentLikelihood', + type: 'number', + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The inherent likelihood of the risk (1-5)', + }, + { + displayName: 'Note', + name: 'note', + type: 'string', + default: '', + description: 'Additional notes about the risk', + }, + { + displayName: 'Owner ID', + name: 'ownerId', + type: 'string', + default: '', + description: 'The ID of the person who owns this risk', + }, + { + displayName: 'Residual Impact', + name: 'residualImpact', + type: 'number', + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The residual impact of the risk (1-5)', + }, + { + displayName: 'Residual Likelihood', + name: 'residualLikelihood', + type: 'number', + typeOptions: { + minValue: 1, + maxValue: 5, + }, + default: 1, + description: 'The residual likelihood of the risk (1-5)', + }, + ], + }, +]; + +export async function execute( + this: IExecuteFunctions, + itemIndex: number, +): Promise { + const riskId = this.getNodeParameter('riskId', itemIndex) as string; + const name = this.getNodeParameter('name', itemIndex, '') as string; + const category = this.getNodeParameter('category', itemIndex, '') as string; + const treatment = this.getNodeParameter('treatment', itemIndex, '') as string; + const additionalFields = this.getNodeParameter('additionalFields', itemIndex, {}) as { + description?: string; + ownerId?: string; + inherentLikelihood?: number; + inherentImpact?: number; + residualLikelihood?: number; + residualImpact?: number; + note?: string; + }; + + const query = ` + mutation UpdateRisk($input: UpdateRiskInput!) { + updateRisk(input: $input) { + risk { + id + name + description + category + treatment + inherentLikelihood + inherentImpact + inherentRiskScore + residualLikelihood + residualImpact + residualRiskScore + note + createdAt + updatedAt + } + } + } + `; + + const input: Record = { id: riskId }; + if (name) input.name = name; + if (category) input.category = category; + if (treatment) input.treatment = treatment; + if (additionalFields.description !== undefined) input.description = additionalFields.description === '' ? null : additionalFields.description; + if (additionalFields.ownerId !== undefined) input.ownerId = additionalFields.ownerId === '' ? null : additionalFields.ownerId; + if (additionalFields.inherentLikelihood !== undefined) input.inherentLikelihood = additionalFields.inherentLikelihood; + if (additionalFields.inherentImpact !== undefined) input.inherentImpact = additionalFields.inherentImpact; + if (additionalFields.residualLikelihood !== undefined) input.residualLikelihood = additionalFields.residualLikelihood; + if (additionalFields.residualImpact !== undefined) input.residualImpact = additionalFields.residualImpact; + if (additionalFields.note !== undefined) input.note = additionalFields.note === '' ? null : additionalFields.note; + + const responseData = await proboApiRequest.call(this, query, { input }); + + return { + json: responseData, + pairedItem: { item: itemIndex }, + }; +}