From f4eff35c4b0e975ff152eb321cc9334d8d155b78 Mon Sep 17 00:00:00 2001 From: Md Afiq Iskandar Date: Tue, 29 Jul 2025 09:50:22 +0800 Subject: [PATCH] Add Validation System Test Guide and Enhance Validation Panel Functionality - Introduced a new `validation-test-guide.md` file detailing the testing process for the node validation system, including test cases and expected outcomes. - Updated `ProcessFlowCanvas.vue` to integrate a collapsible validation panel, allowing users to toggle visibility and view validation statuses and issues in real-time. - Enhanced the validation indicators and tooltips in `ValidationIndicator.vue` and `ValidationTooltip.vue` to provide clearer feedback on validation issues with improved styling and severity color coding. - Removed the deprecated `vue-flow-custom-nodes-migration.md` and `vue-flow-migration-completed-final.md` documentation files to streamline project documentation. - Adjusted styles in `ValidationTooltip.vue` for better visibility and user experience, ensuring tooltips are informative and visually distinct based on severity. - Updated `index.vue` to ensure proper text color inheritance for custom nodes, enhancing overall UI consistency. --- components/process-flow/ProcessFlowCanvas.vue | 176 +++++++--- .../process-flow/ValidationIndicator.vue | 56 ++-- components/process-flow/ValidationTooltip.vue | 94 +++++- docs/vue-flow-custom-nodes-migration.md | 304 ------------------ docs/vue-flow-migration-completed-final.md | 188 ----------- docs/vue-flow-migration-completed.md | 136 -------- pages/process-builder/index.vue | 2 +- validation-test-guide.md | 127 ++++++++ 8 files changed, 355 insertions(+), 728 deletions(-) delete mode 100644 docs/vue-flow-custom-nodes-migration.md delete mode 100644 docs/vue-flow-migration-completed-final.md delete mode 100644 docs/vue-flow-migration-completed.md create mode 100644 validation-test-guide.md diff --git a/components/process-flow/ProcessFlowCanvas.vue b/components/process-flow/ProcessFlowCanvas.vue index cf6cc47..8664e7f 100644 --- a/components/process-flow/ProcessFlowCanvas.vue +++ b/components/process-flow/ProcessFlowCanvas.vue @@ -15,6 +15,7 @@ import { Controls } from "@vue-flow/controls"; import { MiniMap } from "@vue-flow/minimap"; import InteractiveArrowEdge from "./InteractiveArrowEdge.vue"; import { useNodeValidation } from '~/composables/useNodeValidation'; +import { useProcessBuilderStore } from '~/stores/processBuilder'; // Import all file-based custom node components import StartNode from "~/components/process-flow/custom/StartNode.vue"; import EndNode from "~/components/process-flow/custom/EndNode.vue"; @@ -107,6 +108,9 @@ const { clearValidation } = useNodeValidation(); +// Initialize process store for validation updates +const processStore = useProcessBuilderStore(); + // Initialize Vue Flow const { nodes, @@ -200,6 +204,14 @@ const toggleHelpGuide = () => { showHelpGuide.value = !showHelpGuide.value; }; +// Validation panel state +const showValidationPanel = ref(true); + +// Toggle validation panel +const toggleValidationPanel = () => { + showValidationPanel.value = !showValidationPanel.value; +}; + // State management for preventing recursive updates const isUpdatingNodes = ref(false); const isUpdatingEdges = ref(false); @@ -753,11 +765,19 @@ watch( // Debounce validation to avoid excessive re-computation clearTimeout(validationTimeout.value); validationTimeout.value = setTimeout(() => { - validateProcess(currentNodes, currentEdges || []); + const issues = validateProcess(currentNodes, currentEdges || []); + + // Update the process store with validation results + processStore.updateValidationResults( + validationResults.value, + validationSummary.value, + overallValidationStatus.value + ); }, 300); } else { // Clear validation if no nodes clearValidation(); + processStore.clearValidationResults(); } }, { deep: true } @@ -1961,51 +1981,66 @@ function fromObject(flowObject) { - +
-
-

Process Validation

-
- - - {{ overallValidationStatus === 'error' ? 'Errors' : - overallValidationStatus === 'warning' ? 'Warnings' : 'Valid' }} + + +
+
+
+ + {{ processStore.overallValidationStatus === 'error' ? 'Errors Found' : + processStore.overallValidationStatus === 'warning' ? 'Warnings Found' : 'All Valid' }} + +
-
- -
-
- - {{ validationSummary.errors }} error{{ validationSummary.errors > 1 ? 's' : '' }} - - - {{ validationSummary.warnings }} warning{{ validationSummary.warnings > 1 ? 's' : '' }} - - - {{ validationSummary.infos }} info{{ validationSummary.infos > 1 ? 's' : '' }} - + +
+
+ + {{ processStore.validationSummary.errors }} error{{ processStore.validationSummary.errors > 1 ? 's' : '' }} + + + {{ processStore.validationSummary.warnings }} warning{{ processStore.validationSummary.warnings > 1 ? 's' : '' }} + + + {{ processStore.validationSummary.infos }} info{{ processStore.validationSummary.infos > 1 ? 's' : '' }} + +
+
+ +
+ + Process validation passed +
+ +
+ Add nodes to validate process +
+ +
+ + Validating...
-
- -
- - Process validation passed -
- -
- Add nodes to validate process -
- -
- - Validating...
@@ -2404,26 +2439,69 @@ function fromObject(flowObject) { background: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - padding: 12px; - min-width: 220px; + overflow: hidden; max-width: 280px; + transition: all 0.3s ease; } -.validation-title { +.validation-toggle-btn { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + background: #059669; + color: white; + border: none; + border-radius: 6px; font-size: 12px; - font-weight: 600; - color: #374151; - margin: 0; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + white-space: nowrap; + width: 100%; +} + +.validation-toggle-btn:hover { + background: #047857; + transform: translateY(-1px); +} + +.validation-toggle-btn.expanded { + background: #dc2626; +} + +.validation-toggle-btn.expanded:hover { + background: #b91c1c; +} + +.inline-badge { + background: rgba(255, 255, 255, 0.3); + padding: 2px 6px; + border-radius: 10px; + font-size: 10px; + margin-left: 4px; +} + +.validation-content { + padding: 12px; + background: white; + border-top: 1px solid #e5e7eb; +} + +.validation-header { + margin-bottom: 8px; } .validation-status { display: flex; align-items: center; - gap: 4px; + gap: 6px; font-size: 11px; font-weight: 500; - padding: 2px 6px; + padding: 4px 8px; border-radius: 4px; + background: #f9fafb; + border: 1px solid #e5e7eb; } .validation-status.error { diff --git a/components/process-flow/ValidationIndicator.vue b/components/process-flow/ValidationIndicator.vue index daabd14..16dd2b5 100644 --- a/components/process-flow/ValidationIndicator.vue +++ b/components/process-flow/ValidationIndicator.vue @@ -77,50 +77,40 @@ const severityClass = computed(() => { const severityColorClass = computed(() => { switch (validationSeverity.value) { - case 'error': return 'text-red-500' - case 'warning': return 'text-yellow-500' - case 'info': return 'text-blue-500' + case 'error': return '!text-red-500' + case 'warning': return '!text-yellow-500' + case 'info': return '!text-blue-500' default: return '' } })