This commit is contained in:
Mateusz Gruszczyński
2026-09-02 10:12:51 +02:00
parent 8180d22cef
commit e50c94b6a3
19 changed files with 323 additions and 108 deletions
+15 -24
View File
@@ -293,28 +293,19 @@ document.addEventListener('change', event => {
$('#addFlowSharedInput')?.addEventListener('click', () => openFlowSharedInputEditor());
$('#flowSharedInputKind')?.addEventListener('change', event => {
renderFlowSharedInputFields(event.target.value, flowDefaultConfig(event.target.value));
renderFlowSharedInputFields(event.target.value, flowSharedInputDefaultConfig(event.target.value));
});
function compareFlowSharedHaValue(actual, operator, expected) {
if (['lt','lte','gt','gte'].includes(operator)) {
const a = Number(actual), b = Number(expected);
if (!Number.isFinite(a) || !Number.isFinite(b)) return false;
if (operator === 'lt') return a < b;
if (operator === 'lte') return a <= b;
if (operator === 'gt') return a > b;
return a >= b;
}
const left = actual == null ? '' : String(actual);
const right = expected == null ? '' : String(expected);
return operator === 'neq' ? left !== right : left === right;
}
function evaluateFlowSharedHaTest(kind, config, result) {
if (kind === 'ha_available') return { actual:result.state, matched:result.available === true };
let actual = result.state;
if (kind === 'ha_attribute') actual = result.attributes?.[config.attribute];
return { actual, matched:compareFlowSharedHaValue(actual, config.operator || 'eq', config.value) };
if (kind === 'ha_available') return { actual:result.available === true, valid:true };
if (kind === 'ha_attribute') {
const actual = result.attributes?.[config.attribute];
return { actual, valid:actual !== undefined };
}
if (kind === 'ha_numeric') {
const actual = Number(result.state);
return { actual, valid:Number.isFinite(actual) };
}
return { actual:result.state, valid:true };
}
$('#flowSharedInputTest')?.addEventListener('click', async event => {
@@ -336,10 +327,10 @@ $('#flowSharedInputTest')?.addEventListener('click', async event => {
const result = await api('/api/integrations/home-assistant/entity', { method:'POST', body:{ entity_id:entityId } });
const evaluation = evaluateFlowSharedHaTest(kind, config, result);
const actual = evaluation.actual == null ? 'null' : (typeof evaluation.actual === 'object' ? JSON.stringify(evaluation.actual) : String(evaluation.actual));
const expectation = kind === 'ha_available' ? tr('flow.sharedInputTestAvailable') : `${config.operator || 'eq'} ${config.value ?? ''}`;
resultHost.classList.toggle('pass', evaluation.matched);
resultHost.classList.toggle('fail', !evaluation.matched);
resultHost.innerHTML = `<div><strong>${esc(evaluation.matched ? tr('flow.sharedInputTestMatched') : tr('flow.sharedInputTestNotMatched'))}</strong><span class="badge ${evaluation.matched ? 'active' : ''}">${esc(result.available ? tr('flow.sharedInputTestAvailable') : tr('flow.sharedInputTestUnavailable'))}</span></div><dl><div><dt>${esc(tr('flow.sharedInputTestCurrent'))}</dt><dd><code>${esc(actual)}</code></dd></div><div><dt>${esc(tr('flow.sharedInputTestExpected'))}</dt><dd><code>${esc(expectation)}</code></dd></div></dl><small>${esc(result.entity_id)}${result.last_updated ? ` · ${esc(dateTime(result.last_updated))}` : ''}</small>`;
const success = evaluation.valid;
resultHost.classList.toggle('pass', success);
resultHost.classList.toggle('fail', !success);
resultHost.innerHTML = `<div><strong>${esc(success ? tr('flow.sharedInputTestValueRead') : tr('flow.sharedInputTestUnavailable'))}</strong><span class="badge ${success ? 'active' : ''}">${esc(result.available ? tr('flow.sharedInputTestAvailable') : tr('flow.sharedInputTestUnavailable'))}</span></div><dl><div><dt>${esc(tr('flow.sharedInputTestCurrent'))}</dt><dd><code>${esc(actual)}</code></dd></div></dl><small>${esc(result.entity_id)}${result.last_updated ? ` · ${esc(dateTime(result.last_updated))}` : ''}</small>`;
} catch (error) {
resultHost.classList.remove('pass'); resultHost.classList.add('fail');
resultHost.innerHTML = `<strong>${esc(tr('flow.sharedInputTestUnavailable'))}</strong><span>${esc(error.message)}</span>`;