From e54c6d11708f7b277e3bc3750df31cc02af1a380 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Thu, 25 Sep 2025 12:57:42 -0400 Subject: [PATCH 1/2] Check for false positive validation errors for PM Blocks --- src/components/modeler/Modeler.vue | 50 ++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/components/modeler/Modeler.vue b/src/components/modeler/Modeler.vue index 6e912c2d9..d8e01ed14 100644 --- a/src/components/modeler/Modeler.vue +++ b/src/components/modeler/Modeler.vue @@ -1071,7 +1071,7 @@ export default { }, validateIfAutoValidateIsOn() { if (this.autoValidate) { - this.validateBpmnDiagram(); + this.safeRevalidate(); } }, translateConfig(inspectorConfig) { @@ -1114,9 +1114,53 @@ export default { if (!store.getters.globalProcesses || store.getters.globalProcesses.length === 0) { await store.dispatch('fetchGlobalProcesses'); } + this.validationErrors = await this.linter.lint(this.definitions); + + // Filter out false positive validation errors for properly configured PM Blocks + this.filterFalsePositivePMBlockErrors(); + this.$emit('validate', this.validationErrors); }, + filterFalsePositivePMBlockErrors() { + // Filter out false positive validation errors for properly configured PM Blocks + if (this.validationErrors['processmaker/call-activity-child-process']) { + const originalErrors = this.validationErrors['processmaker/call-activity-child-process']; + const filteredErrors = originalErrors.filter(error => { + // Find the corresponding node + const node = this.nodes.find(n => n.definition.id === error.id); + if (!node || !node.isBpmnType('bpmn:CallActivity')) { + return true; // Keep the error if we can't find the node + } + + // Check if the PM Block is properly configured + const hasCalledElement = node.definition.calledElement && node.definition.calledElement !== ''; + const hasConfig = node.definition.config && node.definition.config !== '{}'; + + if (!hasCalledElement || !hasConfig) { + return true; // Keep the error if the PM Block is genuinely unconfigured + } + + // Parse the config and check for required fields + try { + const config = JSON.parse(node.definition.config); + const hasProcessId = config.processId && config.processId !== null; + const hasStartEvent = config.startEvent && config.startEvent !== null; + + if (!hasProcessId || !hasStartEvent) { + return true; // Keep the error if required fields are missing + } + + // If PM Block is properly configured, remove the error + return false; + } catch (e) { + return true; // Keep the error if config parsing fails + } + }); + + this.validationErrors['processmaker/call-activity-child-process'] = filteredErrors; + } + }, setPools(poolDefinition) { if (!this.collaboration) { this.collaboration = this.moddle.create('bpmn:Collaboration'); @@ -1610,7 +1654,7 @@ export default { await this.$nextTick(); await this.paperManager.awaitScheduledUpdates(); if (this.autoValidate) { - this.validateBpmnDiagram(); + this.safeRevalidate(); } }, @@ -2560,6 +2604,7 @@ export default { async safeRevalidate() { // Run bpmnlint only when auto-validate is enabled and the model is ready. if (!this.autoValidate) return; + // Wait for Vue and JointJS to settle before validating, so we don't lose errors await this.$nextTick(); if (this.paperManager?.awaitScheduledUpdates) { @@ -2615,6 +2660,7 @@ export default { this.initTransparentDragging(); this.test = true; this.adjustPaperPosition(); + this.safeRevalidate(); }, }; From bbca9676107f91894ca1c07666ff4717ba113773 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Thu, 25 Sep 2025 13:33:13 -0400 Subject: [PATCH 2/2] Resolve code smells --- src/components/modeler/Modeler.vue | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/modeler/Modeler.vue b/src/components/modeler/Modeler.vue index d8e01ed14..a704a9402 100644 --- a/src/components/modeler/Modeler.vue +++ b/src/components/modeler/Modeler.vue @@ -1147,14 +1147,13 @@ export default { const hasProcessId = config.processId && config.processId !== null; const hasStartEvent = config.startEvent && config.startEvent !== null; - if (!hasProcessId || !hasStartEvent) { - return true; // Keep the error if required fields are missing + // If PM Block is properly configured, remove the error; otherwise keep it + return !(hasProcessId && hasStartEvent); + } catch (error) { + if (error instanceof SyntaxError) { + return true; // Keep the error if config is invalid JSON or parsing fails } - - // If PM Block is properly configured, remove the error - return false; - } catch (e) { - return true; // Keep the error if config parsing fails + throw error; } });