#!/usr/bin/env python3 import json with open('/home/mdares/.node-red/flows.json', 'r') as f: flows = json.load(f) print("IMPLEMENTING CLEAN STOP PROMPT") print("="*60) # ============================================================================ # STEP 1: Update Work Order buttons STOP case # ============================================================================ for node in flows: if node.get('id') == '9bbd4fade968036d': # Work Order buttons func = node.get('func', '') # Find and replace the STOP case old_stop = ''' case "stop": { // Manual STOP button clicked from Home dashboard global.set("trackingEnabled", false); node.warn("[STOP] Production tracking disabled"); return [null, null, null, null, null]; }''' new_stop = ''' case "stop": { // Manual STOP button clicked from Home dashboard // Immediately disable tracking global.set("trackingEnabled", false); node.warn("[STOP] Tracking disabled - prompting for reason"); // Send response back to Home to show prompt msg._stopPrompt = true; msg.topic = "showStopPrompt"; msg.payload = { timestamp: Date.now(), workOrderId: (global.get("activeWorkOrder") || {}).id || null }; // Return on output 1 (goes to Base64 -> link out 3 -> link in 3 -> Home) return [msg, null, null, null, null]; }''' func = func.replace(old_stop, new_stop) node['func'] = func print("✅ Updated Work Order buttons STOP case") print(" - Returns msg on output 1 with _stopPrompt flag") break # ============================================================================ # STEP 2: Update Home Template to show prompt on showStopPrompt topic # ============================================================================ for node in flows: if node.get('id') == '1821c4842945ecd8': # Home Template template = node.get('format', '') # Add handler for showStopPrompt in the message watch # Find where to insert - after machineStatus handler insert_point = template.find("if (msg.topic === 'kpiUpdate')") if insert_point > 0: stop_prompt_handler = ''' // Show stop reason prompt if (msg.topic === 'showStopPrompt' || msg._stopPrompt) { console.log('[STOP PROMPT] Showing prompt'); document.getElementById('stopReasonModal').style.display = 'flex'; return; } ''' template = template[:insert_point] + stop_prompt_handler + template[insert_point:] print("✅ Added showStopPrompt handler to Home Template") # Now ensure the modal div has an ID and uses display:none instead of ng-show # Find the stop modal div modal_div_pos = template.find('
0: # Find the opening div tag div_start = template.rfind('', div_start) div_tag = template[div_start:div_end+1] if 'id=' not in div_tag: # Add id to this div new_div_tag = div_tag.replace('
') if stop_modal_start > 0: # Find the opening div after this comment modal_div = template.find('', modal_div) # Get the div tag div_tag = template[modal_div:modal_div_end+1] # Replace ng-show with inline style if 'ng-show' in div_tag: # Remove ng-show and add style="display:none" new_div = div_tag.replace('ng-show="stopPrompt.show"', 'style="display:none"') new_div = new_div.replace('ng-click="stopPrompt.show = false"', 'onclick="hideStopPrompt()"') template = template.replace(div_tag, new_div) print("✅ Replaced ng-show with display:none for stop modal") # Update the JavaScript functions to use vanilla JS # Find submitStopReason function submit_fn_pos = template.find('scope.submitStopReason = function()') if submit_fn_pos > 0: # Replace scope-based logic with vanilla JS old_submit = '''scope.submitStopReason = function() { if (!scope.stopPrompt.selectedCategory || !scope.stopPrompt.selectedReason) { return; } // Send stop reason to Node-RED scope.send({ action: 'stop-reason', payload: { category: scope.stopPrompt.selectedCategory, reason: scope.stopPrompt.selectedReason, notes: scope.stopPrompt.notes || '' } }); // Close the modal scope.stopPrompt.show = false; };''' new_submit = '''window.submitStopReason = function() { const category = window._stopCategory; const reason = window._stopReason; if (!category || !reason) { alert('Please select a stop reason'); return; } const notes = document.getElementById('stopReasonNotes').value; // Send stop reason to Node-RED scope.send({ action: 'stop-reason', payload: { category: category, reason: reason, notes: notes } }); // Close the modal hideStopPrompt(); }; window.hideStopPrompt = function() { document.getElementById('stopReasonModal').style.display = 'none'; };''' template = template.replace(old_submit, new_submit) print("✅ Converted submitStopReason to vanilla JavaScript") # Update selectStopReason to use vanilla JS select_fn_pos = template.find('scope.selectStopReason = function') if select_fn_pos > 0: old_select = '''scope.selectStopReason = function(category, reason) { scope.stopPrompt.selectedCategory = category; scope.stopPrompt.selectedReason = reason; };''' new_select = '''window.selectStopReason = function(category, reason) { window._stopCategory = category; window._stopReason = reason; // Update UI - remove all selected classes document.querySelectorAll('.stop-reason-option').forEach(btn => { btn.classList.remove('selected'); }); // Add selected class to clicked button event.target.closest('.stop-reason-option').classList.add('selected'); // Enable submit button document.getElementById('submitStopReason').disabled = false; };''' template = template.replace(old_select, new_select) print("✅ Converted selectStopReason to vanilla JavaScript") # Update button onclick handlers to use window functions template = template.replace('ng-click="selectStopReason(', 'onclick="selectStopReason(') template = template.replace('ng-click="submitStopReason()"', 'onclick="submitStopReason()"') template = template.replace('ng-disabled="!stopPrompt.selectedReason"', 'id="submitStopReason" disabled') print("✅ Updated button handlers to vanilla JavaScript") node['format'] = template break # Save with open('/home/mdares/.node-red/flows.json', 'w') as f: json.dump(flows, f, indent=4) print("\n" + "="*60) print("✅ CLEAN STOP PROMPT IMPLEMENTED") print("="*60) print("\nWhat was done:") print(" 1. STOP case now returns message on output 1") print(" 2. Home receives showStopPrompt topic") print(" 3. Modal shown with vanilla JS (no Angular scope)") print(" 4. All handlers converted to vanilla JavaScript") print(" 5. Clean, simple, reliable!") print("\nHow it works:") print(" 1. Click STOP → tracking disabled immediately") print(" 2. Modal appears (plain JS, no routing)") print(" 3. Select reason → sends stop-reason action") print(" 4. Done!") print("\nRESTART NODE-RED AND TEST!")