233 lines
8.4 KiB
Python
233 lines
8.4 KiB
Python
#!/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('<div id="stopReasonModal"')
|
|
|
|
if modal_div_pos < 0:
|
|
# The modal doesn't have id="stopReasonModal", need to fix it
|
|
# Find the stop modal by class
|
|
modal_search = template.find('class="stop-reason-modal"')
|
|
if modal_search > 0:
|
|
# Find the opening div tag
|
|
div_start = template.rfind('<div', modal_search - 100, modal_search)
|
|
# Check if it has an id already
|
|
div_end = template.find('>', 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('<div ', '<div id="stopReasonModal" ')
|
|
template = template.replace(div_tag, new_div_tag)
|
|
print("✅ Added id='stopReasonModal' to stop modal div")
|
|
|
|
# Find the stop modal in the HTML we added earlier
|
|
# Look for the div with stop-reason-modal class
|
|
stop_modal_start = template.find('<!-- Stop Reason Modal -->')
|
|
if stop_modal_start > 0:
|
|
# Find the opening div after this comment
|
|
modal_div = template.find('<div', stop_modal_start)
|
|
modal_div_end = 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!")
|