Initial commit, 90% there
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
#!/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!")
|
||||
Reference in New Issue
Block a user