mirror of
http://10.0.2.1:3031/sauer/bfa-dryer-design.git
synced 2026-06-30 12:56:42 +10:00
Custom card colors (text/active/inactive), smart automation toggle logic
This commit is contained in:
parent
b76cb7be9e
commit
61605fb7f2
@ -466,6 +466,14 @@ function createCardEl(c) {
|
|||||||
const s = simState[c.id] || {on: false, value: 0};
|
const s = simState[c.id] || {on: false, value: 0};
|
||||||
if (c.type !== 'temp' && s.on) el.classList.add('on');
|
if (c.type !== 'temp' && s.on) el.classList.add('on');
|
||||||
|
|
||||||
|
// Apply custom colors
|
||||||
|
if (c.type !== 'temp') {
|
||||||
|
const onColor = c.activeColor || (c.type === 'burner' ? 'var(--amber)' : 'var(--green)');
|
||||||
|
const offColor = c.inactiveColor || 'var(--red)';
|
||||||
|
el.style.background = s.on ? onColor : offColor;
|
||||||
|
}
|
||||||
|
if (c.textColor) el.style.color = c.textColor;
|
||||||
|
|
||||||
// Drag handle (edit mode)
|
// Drag handle (edit mode)
|
||||||
el.innerHTML = `<span class="drag-handle edit-overlay">☰</span>`;
|
el.innerHTML = `<span class="drag-handle edit-overlay">☰</span>`;
|
||||||
|
|
||||||
@ -779,14 +787,28 @@ function editCardProps(id) {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="prop-row">
|
<div class="prop-row">
|
||||||
<label>Color</label>
|
<label>Text Color</label>
|
||||||
|
<input type="color" id="prop-textcolor" value="${card.textColor||'#e8ecf4'}">
|
||||||
|
<span class="prop-preview" style="background:${card.textColor||'#e8ecf4'}"></span>
|
||||||
|
</div>
|
||||||
|
<div class="prop-row">
|
||||||
|
<label>ON Color</label>
|
||||||
|
<input type="color" id="prop-activecolor" value="${card.activeColor||(card.type==='burner'?'#ffab00':'#00c853')}">
|
||||||
|
<span class="prop-preview" style="background:${card.activeColor||(card.type==='burner'?'#ffab00':'#00c853')}"></span>
|
||||||
|
</div>
|
||||||
|
<div class="prop-row">
|
||||||
|
<label>OFF Color</label>
|
||||||
|
<input type="color" id="prop-inactivecolor" value="${card.inactiveColor||'#ff1744'}">
|
||||||
|
<span class="prop-preview" style="background:${card.inactiveColor||'#ff1744'}"></span>
|
||||||
|
</div>
|
||||||
|
<div class="prop-row">
|
||||||
|
<label>Accent Color</label>
|
||||||
<input type="color" id="prop-color" value="${card.color||'#ff8844'}">
|
<input type="color" id="prop-color" value="${card.color||'#ff8844'}">
|
||||||
<span class="prop-preview" id="prop-color-preview" style="background:${card.color||'#ff8844'}"></span>
|
<span class="prop-preview" id="prop-color-preview" style="background:${card.color||'#ff8844'}"></span>
|
||||||
<button onclick="document.getElementById('prop-color').value='';document.getElementById('prop-color-preview').style.background='var(--card)'" style="padding:6px 10px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--text2);font-size:11px;cursor:pointer">Reset</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="prop-row">
|
<div class="prop-row">
|
||||||
<label>Font Size</label>
|
<label>Font Size</label>
|
||||||
<input type="range" id="prop-fontsize" min="12" max="36" value="${card.fontSize||18}">
|
<input type="range" id="prop-fontsize" min="12" max="48" value="${card.fontSize||18}">
|
||||||
<span id="prop-fontsize-val" style="color:var(--text2);min-width:30px">${card.fontSize||18}px</span>
|
<span id="prop-fontsize-val" style="color:var(--text2);min-width:30px">${card.fontSize||18}px</span>
|
||||||
</div>
|
</div>
|
||||||
${extraFields}
|
${extraFields}
|
||||||
@ -816,6 +838,9 @@ function saveCardProps(id) {
|
|||||||
card.width = document.getElementById('prop-width').value;
|
card.width = document.getElementById('prop-width').value;
|
||||||
const color = document.getElementById('prop-color').value;
|
const color = document.getElementById('prop-color').value;
|
||||||
card.color = color || null;
|
card.color = color || null;
|
||||||
|
card.textColor = document.getElementById('prop-textcolor').value || null;
|
||||||
|
card.activeColor = document.getElementById('prop-activecolor').value || null;
|
||||||
|
card.inactiveColor = document.getElementById('prop-inactivecolor').value || null;
|
||||||
card.fontSize = parseInt(document.getElementById('prop-fontsize').value) || 18;
|
card.fontSize = parseInt(document.getElementById('prop-fontsize').value) || 18;
|
||||||
|
|
||||||
const spEl = document.getElementById('prop-sp');
|
const spEl = document.getElementById('prop-sp');
|
||||||
@ -850,21 +875,54 @@ function toggleSim(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is an automation card, activate/deactivate all its rules
|
// Automation logic: activating one deactivates others, but shared outputs stay on
|
||||||
if (card && card.type === 'automation' && card.rules) {
|
if (card && card.type === 'automation') {
|
||||||
card.rules.forEach(r => {
|
if (simState[id].on && card.rules) {
|
||||||
if (!r.target) return;
|
// Collect all targets this automation activates
|
||||||
if (!simState[r.target]) simState[r.target] = {on: false, value: 0};
|
const myTargets = new Set();
|
||||||
if (simState[id].on) {
|
card.rules.forEach(r => { if (r.target) myTargets.add(r.target); });
|
||||||
// Activating: apply all rules
|
|
||||||
|
// Deactivate other automation cards, but track what they had on
|
||||||
|
const allAutoCards = [];
|
||||||
|
layout.pages.forEach(p => p.cards.forEach(c => {
|
||||||
|
if (c.type === 'automation' && c.id !== id) allAutoCards.push(c);
|
||||||
|
}));
|
||||||
|
|
||||||
|
allAutoCards.forEach(ac => {
|
||||||
|
if (simState[ac.id] && simState[ac.id].on) {
|
||||||
|
// Turn off this automation
|
||||||
|
simState[ac.id].on = false;
|
||||||
|
// Turn off its outputs ONLY if not shared with the new automation
|
||||||
|
(ac.rules || []).forEach(r => {
|
||||||
|
if (r.target && !myTargets.has(r.target)) {
|
||||||
|
if (simState[r.target] && r.action !== 'off') simState[r.target].on = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Now apply this automation's rules
|
||||||
|
card.rules.forEach(r => {
|
||||||
|
if (!r.target) return;
|
||||||
|
if (!simState[r.target]) simState[r.target] = {on: false, value: 0};
|
||||||
if (r.action === 'on') simState[r.target].on = true;
|
if (r.action === 'on') simState[r.target].on = true;
|
||||||
else if (r.action === 'off') simState[r.target].on = false;
|
else if (r.action === 'off') simState[r.target].on = false;
|
||||||
else if (r.action === 'set') { simState[r.target].on = true; simState[r.target].value = r.value || 0; }
|
else if (r.action === 'set') { simState[r.target].on = true; simState[r.target].value = r.value || 0; }
|
||||||
} else {
|
});
|
||||||
// Deactivating: turn everything off
|
} else if (!simState[id].on && card.rules) {
|
||||||
if (r.action !== 'off') simState[r.target].on = false;
|
// Deactivating: turn off outputs that no other active automation needs
|
||||||
}
|
const otherActiveTargets = new Set();
|
||||||
});
|
layout.pages.forEach(p => p.cards.forEach(c => {
|
||||||
|
if (c.type === 'automation' && c.id !== id && simState[c.id] && simState[c.id].on) {
|
||||||
|
(c.rules || []).forEach(r => { if (r.target) otherActiveTargets.add(r.target); });
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
card.rules.forEach(r => {
|
||||||
|
if (r.target && !otherActiveTargets.has(r.target) && r.action !== 'off') {
|
||||||
|
if (simState[r.target]) simState[r.target].on = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCards();
|
renderCards();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user