Files
2025-12-02 16:27:21 +00:00

250 lines
10 KiB
Python

#!/usr/bin/env python3
import json
with open('/home/mdares/.node-red/flows.json', 'r') as f:
flows = json.load(f)
print("REWRITING STOP MODAL TO MATCH SCRAP MODAL PATTERN")
print("="*60)
for node in flows:
if node.get('id') == '1821c4842945ecd8':
template = node.get('format', '')
# STEP 1: Initialize stopPrompt in message handler (like scrapPrompt)
init_pos = template.find("if (!scope.scrapPrompt)")
if init_pos > 0:
# Add stopPrompt initialization right after scrapPrompt
scrap_init_end = template.find("};", init_pos) + 2
stop_init = '''
if (!scope.stopPrompt) {
scope.stopPrompt = {
show: false,
selectedCategory: null,
selectedReason: null,
notes: ''
};
}'''
template = template[:scrap_init_end] + stop_init + template[scrap_init_end:]
print("✅ Added stopPrompt initialization")
# STEP 2: Replace stop modal HTML to use ng-show (like scrap)
# Find current stop modal
stop_modal_start = template.find('<!-- Stop Reason Modal -->')
if stop_modal_start > 0:
# Find end of modal
stop_modal_end = template.find('</div>\n</div>', stop_modal_start + 100)
# Keep going until we find the actual end
count = 0
pos = stop_modal_start
while count < 3: # Modal has 3 nested divs
pos = template.find('</div>', pos + 1)
count += 1
stop_modal_end = pos + 6
# Replace entire modal with ng-show version
new_stop_modal = '''<!-- Stop Reason Modal -->
<div id="stopReasonModal" class="modal" ng-show="stopPrompt.show">
<div class="modal-card modal-card-stop">
<div class="modal-header-stop">
<span>⚠️ Production Stopped</span>
</div>
<div class="modal-body">
<p class="stop-question">Why are you stopping production?</p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem;">
<!-- Planned Stops Column -->
<div class="stop-category-section">
<div class="stop-category-header planned-header">
<span>📋 Planned</span>
</div>
<div class="stop-reasons-list">
<button class="stop-reason-option planned"
ng-class="{selected: stopPrompt.selectedCategory === 'planned' && stopPrompt.selectedReason === 'Lunch break'}"
ng-click="selectStopReason('planned', 'Lunch break')">
🍽️ Lunch break
</button>
<button class="stop-reason-option planned"
ng-class="{selected: stopPrompt.selectedCategory === 'planned' && stopPrompt.selectedReason === 'Scheduled break'}"
ng-click="selectStopReason('planned', 'Scheduled break')">
☕ Scheduled break
</button>
<button class="stop-reason-option planned"
ng-class="{selected: stopPrompt.selectedCategory === 'planned' && stopPrompt.selectedReason === 'Shift change'}"
ng-click="selectStopReason('planned', 'Shift change')">
🔄 Shift change
</button>
<button class="stop-reason-option planned"
ng-class="{selected: stopPrompt.selectedCategory === 'planned' && stopPrompt.selectedReason === 'Planned maintenance'}"
ng-click="selectStopReason('planned', 'Planned maintenance')">
🔧 Maintenance
</button>
</div>
</div>
<!-- Unplanned Stops Column -->
<div class="stop-category-section">
<div class="stop-category-header unplanned-header">
<span>🚨 Unplanned</span>
</div>
<div class="stop-reasons-list">
<button class="stop-reason-option unplanned"
ng-class="{selected: stopPrompt.selectedCategory === 'unplanned' && stopPrompt.selectedReason === 'Machine malfunction'}"
ng-click="selectStopReason('unplanned', 'Machine malfunction')">
⚙️ Malfunction
</button>
<button class="stop-reason-option unplanned"
ng-class="{selected: stopPrompt.selectedCategory === 'unplanned' && stopPrompt.selectedReason === 'Material shortage'}"
ng-click="selectStopReason('unplanned', 'Material shortage')">
📦 Material
</button>
<button class="stop-reason-option unplanned"
ng-class="{selected: stopPrompt.selectedCategory === 'unplanned' && stopPrompt.selectedReason === 'Quality issue'}"
ng-click="selectStopReason('unplanned', 'Quality issue')">
❌ Quality
</button>
<button class="stop-reason-option unplanned"
ng-class="{selected: stopPrompt.selectedCategory === 'unplanned' && stopPrompt.selectedReason === 'Operator error'}"
ng-click="selectStopReason('unplanned', 'Operator error')">
👤 Operator
</button>
<button class="stop-reason-option unplanned"
ng-class="{selected: stopPrompt.selectedCategory === 'unplanned' && stopPrompt.selectedReason === 'Other'}"
ng-click="selectStopReason('unplanned', 'Other')">
❓ Other
</button>
</div>
</div>
</div>
<!-- Notes spanning both columns -->
<div class="stop-notes-section">
<label class="stop-notes-label">Additional notes (optional):</label>
<textarea class="stop-notes-input" ng-model="stopPrompt.notes"
placeholder="Enter any additional details..."></textarea>
</div>
<!-- Action buttons -->
<div class="modal-actions">
<button class="stop-reason-cancel" ng-click="stopPrompt.show = false">Cancel</button>
<button class="stop-reason-submit"
ng-disabled="!stopPrompt.selectedReason"
ng-click="submitStopReason()">
Submit
</button>
</div>
</div>
</div>
</div>'''
template = template[:stop_modal_start] + new_stop_modal + template[stop_modal_end:]
print("✅ Replaced stop modal HTML with ng-show version")
# STEP 3: Rewrite functions to match scrap pattern
# Find and replace selectStopReason
select_fn_start = template.find('scope.selectStopReason')
if select_fn_start > 0:
select_fn_end = template.find('};', select_fn_start) + 2
new_select = '''scope.selectStopReason = function(category, reason) {
scope.stopPrompt.selectedCategory = category;
scope.stopPrompt.selectedReason = reason;
console.log('[SELECT] Reason:', category, reason);
};'''
template = template[:select_fn_start] + new_select + template[select_fn_end:]
print("✅ Simplified selectStopReason")
# Replace submitStopReason
submit_fn_start = template.find('scope.submitStopReason')
if submit_fn_start > 0:
submit_fn_end = template.find('};', template.find('};', submit_fn_start) + 1) + 2
new_submit = '''scope.submitStopReason = function() {
if (!scope.stopPrompt.selectedCategory || !scope.stopPrompt.selectedReason) {
return;
}
console.log('[STOP] Submitting reason:', scope.stopPrompt.selectedCategory, scope.stopPrompt.selectedReason);
// Send stop-reason to backend
scope.send({
action: 'stop-reason',
payload: {
category: scope.stopPrompt.selectedCategory,
reason: scope.stopPrompt.selectedReason,
notes: scope.stopPrompt.notes || ''
}
});
// Update UI - production stopped
scope.isProductionRunning = false;
// Close modal
scope.stopPrompt.show = false;
scope.stopPrompt.selectedCategory = null;
scope.stopPrompt.selectedReason = null;
scope.stopPrompt.notes = '';
};'''
template = template[:submit_fn_start] + new_submit + template[submit_fn_end:]
print("✅ Rewrote submitStopReason to match scrap pattern")
# STEP 4: Update toggleStartStop to set scope.stopPrompt.show = true
toggle_start = template.find('scope.toggleStartStop = function()')
if toggle_start > 0:
toggle_end = template.find('};', toggle_start) + 2
new_toggle = '''scope.toggleStartStop = function() {
if (scope.isProductionRunning) {
// STOP clicked - show prompt
console.log('[STOP] Showing stop prompt');
scope.stopPrompt.show = true;
scope.stopPrompt.selectedCategory = null;
scope.stopPrompt.selectedReason = null;
scope.stopPrompt.notes = '';
} else {
// START clicked
scope.send({ action: "start" });
scope.isProductionRunning = true;
}
};'''
template = template[:toggle_start] + new_toggle + template[toggle_end:]
print("✅ Updated toggleStartStop to use scope.stopPrompt.show")
# STEP 5: Update CSS for 2-column layout
css_pos = template.find('.stop-reasons-grid')
if css_pos > 0:
# Replace with stop-reasons-list for vertical layout
template = template.replace('.stop-reasons-grid {', '.stop-reasons-list {')
template = template.replace('grid-template-columns: 1fr 1fr;', 'display: flex; flex-direction: column;')
template = template.replace('gap: 0.75rem;', 'gap: 0.5rem;')
print("✅ Updated CSS for vertical button layout")
# Make modal more compact
template = template.replace('max-width: 700px;', 'max-width: 600px;')
template = template.replace('padding: 1.5rem;', 'padding: 1rem;')
node['format'] = template
break
with open('/home/mdares/.node-red/flows.json', 'w') as f:
json.dump(flows, f, indent=4)
print("\n" + "="*60)
print("✅ STOP MODAL NOW MATCHES SCRAP MODAL PATTERN")
print("="*60)
print("\nChanges:")
print(" 1. Uses ng-show (like scrap)")
print(" 2. Uses ng-click (like scrap)")
print(" 3. Uses ng-model for notes (like scrap)")
print(" 4. Uses ng-disabled for submit (like scrap)")
print(" 5. Simple scope functions (like scrap)")
print(" 6. 2-column layout with buttons in vertical lists")
print("\nRESTART NODE-RED - THIS WILL WORK LIKE SCRAP!")