#!/usr/bin/env python3 import json # Read flows.json with open('/home/mdares/.node-red/flows.json', 'r') as f: flows = json.load(f) # Find Home template home_template_node = None for node in flows: if node.get('id') == '1821c4842945ecd8': home_template_node = node break if not home_template_node: print("❌ ERROR: Could not find Home template") exit(1) template_code = home_template_node.get('format', '') # ============================================================================ # PART 1: Add message handler for stop-prompt # ============================================================================ # Find where to insert the handler - after scrapPrompt handler insert_point = template_code.find("if (msg.topic === 'scrapPrompt')") if insert_point < 0: print("❌ ERROR: Could not find scrapPrompt handler") exit(1) # Find the end of the scrapPrompt handler block (find the next "if (msg" after it) next_handler_start = template_code.find("\n if (msg", insert_point + 100) if next_handler_start < 0: # Try to find end of watch block next_handler_start = template_code.find("\n });", insert_point + 100) stop_prompt_handler = ''' // Stop Reason Prompt Handler if (!scope.stopPrompt) { scope.stopPrompt = { show: false, selectedCategory: null, selectedReason: null, notes: '' }; } if (msg._mode === 'stop-prompt') { scope.stopPrompt.show = true; scope.stopPrompt.selectedCategory = null; scope.stopPrompt.selectedReason = null; scope.stopPrompt.notes = ''; scope.$applyAsync(); return; } ''' # Insert the handler template_code = template_code[:next_handler_start] + stop_prompt_handler + template_code[next_handler_start:] print("✅ Added stop prompt message handler") # ============================================================================ # PART 2: Add stop prompt modal HTML # ============================================================================ # Find where scrap modal is defined (should be near the end, before closing tags) # Look for closing div tags at the end scrap_modal_end = template_code.rfind('\n\n\n ''' # Insert the modal HTML template_code = template_code[:scrap_modal_end] + stop_modal_html + template_code[scrap_modal_end:] print("✅ Added stop prompt modal HTML") # ============================================================================ # PART 3: Add CSS for stop modal (matching scrap modal theme) # ============================================================================ # Find where CSS is defined (look for ') if css_end < 0: print("❌ ERROR: Could not find CSS section") exit(1) stop_modal_css = ''' /* Stop Reason Modal Styling */ .modal-card-stop { width: min(90vw, 36rem); max-height: 85vh; overflow-y: auto; } .modal-header-stop { background: linear-gradient(135deg, #d32f2f 0%, #f44336 100%); color: white; padding: 1rem; font-size: var(--fs-section-title); font-weight: 600; border-radius: 0.5rem 0.5rem 0 0; } .stop-question { font-size: var(--fs-label-lg); text-align: center; margin-bottom: 1rem; color: var(--text); font-weight: 500; } .stop-category-section { margin-bottom: 1.5rem; } .stop-category-header { padding: 0.5rem 0.75rem; border-radius: 0.25rem; margin-bottom: 0.5rem; font-weight: 600; display: flex; justify-content: space-between; align-items: center; } .stop-category-header.planned-header { background: #e8f5e9; color: #2e7d32; } .stop-category-header.unplanned-header { background: #ffebee; color: #c62828; } .stop-category-note { font-size: 0.75rem; font-weight: 400; opacity: 0.8; } .stop-reasons-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 0.5rem; } .stop-reason-option { padding: 0.75rem; border: 2px solid var(--border); background: white; border-radius: 0.5rem; cursor: pointer; transition: all 0.2s; display: flex; flex-direction: column; align-items: center; gap: 0.25rem; text-align: center; } .stop-reason-option:hover { border-color: var(--accent); background: var(--surface); transform: translateY(-2px); box-shadow: 0 2px 8px rgba(0,0,0,0.1); } .stop-reason-option.selected { border-color: var(--accent); background: var(--accent); color: white; font-weight: 600; } .stop-reason-option.planned { border-left: 4px solid #4caf50; } .stop-reason-option.unplanned { border-left: 4px solid #f44336; } .stop-reason-option.planned.selected { border-color: #4caf50; background: #4caf50; } .stop-reason-option.unplanned.selected { border-color: #f44336; background: #f44336; } .reason-icon { font-size: 1.5rem; } .reason-text { font-size: 0.85rem; } .stop-notes-section { margin-bottom: 1rem; } .stop-notes-label { display: block; margin-bottom: 0.5rem; font-weight: 500; color: var(--text); } .stop-notes-input { width: 100%; padding: 0.75rem; border: 1px solid var(--border); border-radius: 0.375rem; font-family: inherit; font-size: var(--fs-body); resize: vertical; min-height: 4rem; background: white; } .stop-notes-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1); } ''' template_code = template_code[:css_end] + stop_modal_css + template_code[css_end:] print("✅ Added stop prompt CSS") # ============================================================================ # PART 4: Add JavaScript functions for stop modal # ============================================================================ # Find where JavaScript functions are (after