Skip to content

Fall back to gray when matching state has no color + document JSON schema#30

Open
robmarcer wants to merge 1 commit into
FlowFuse:mainfrom
robmarcer:fix/fallback-color-when-state-color-missing
Open

Fall back to gray when matching state has no color + document JSON schema#30
robmarcer wants to merge 1 commit into
FlowFuse:mainfrom
robmarcer:fix/fallback-color-when-state-color-missing

Conversation

@robmarcer

Copy link
Copy Markdown

Problem

When msg.payload matches a configured state but that state has no color set, the computed color is undefined. That value is interpolated into the inline style as the literal string --ui-led-color: undefined;, which is an invalid CSS value, so background-color: var(--ui-led-color) resolves to nothing and the bulb becomes invisible — no warning in the console, no fallback color, just a label with empty space where the LED should be.

This is easy to hit in a few real scenarios:

  • A flow is hand-crafted or generated by tooling (scripts, LLMs) and the author guesses the field name (colorForValue, colours, etc.) instead of the correct states. The widget then has zero rules, the for loop doesn't iterate, and the fallback 'gray' kicks in — that case already works. BUT if they get the field name right but forget color on a state entry, the result is invisible.
  • The editor's HTML defaults set up two states entries ({value: false, valueType: 'bool'} and {value: true, valueType: 'bool'}) with no color field. An engineer who deploys without opening the Values dialog gets invisible LEDs.
  • A flow is imported from another instance where color was stripped (some flow editors / migration tools normalise default-equal fields out of stored JSON).

In all three cases the LED is silently invisible. We hit it on a customer engagement; the only diagnosis path was reading the Vue component source, which isn't ideal for users.

Fix

ui/components/UILed.vue: when a state matches but state.color is falsy, return 'gray' instead of undefined. Same fallback the function already uses for "no match found" and "no value received yet" — extends it to cover the "matched state, no color set" case so the bulb is never silently invisible.

Also restructures the match check into a single matched boolean to keep the result-resolution in one place.

No behaviour change for correctly-configured LEDs.

Docs

README.md: adds a "JSON config" section documenting the underlying states field name. The editor labels this section "Values"; the underlying node property is states. This trips up users hand-editing flow JSON or generating it from scripts (including this engagement — several wrong guesses before reading the source).

Also reworded the existing "If a value is provided that it doesn't recognise" bullet to mention the missing-color fallback explicitly, matching the new behaviour.

Testing

  • Manual: deployed the change with a ui-led whose state entries lacked colors. Before: invisible. After: gray bulb (visibly there, just neutral).
  • Existing LEDs with correct color config: unchanged — green/red/etc. still render as configured.
  • The gray fallback fires in three independent code paths now: no value yet (existing), no state matches (existing), matching state has no color (new).

Notes

  • This stops short of changing the HTML defaults to include sensible color values for the default states (would change UX for existing users who currently see invisible LEDs but then add colors via the editor). Open to doing that as a follow-up if you think it's a clearer fix.

…hema

When a `state` matches the incoming `msg.payload` but its `color`
field is missing, the computed `color` is `undefined`. That ends up
in the inline style as the literal string `--ui-led-color: undefined;`,
which is an invalid CSS value, so `background-color: var(--ui-led-color)`
resolves to nothing and the bulb becomes invisible — no warning, no
fallback.

This is easy to hit when:
- a flow is built by hand or generated by tooling (LLMs, scripts) and
  the author uses the wrong field name (e.g. `colorForValue`) or
  forgets `color` on a state entry,
- the editor's defaults are kept (the schema's default `states` array
  has entries without `color`), and a deploy happens before the
  engineer opens the Values dialog,
- a flow is imported from another instance where the `color` was
  stripped (some Dashboard editors normalise default-equal fields out).

This change preserves the existing "no matching state -> gray" fallback
and extends it to "matching state with no color -> gray". The LED is
never silently invisible again; at worst it renders gray.

Also restructures the match check into a single `matched` predicate
to keep the two output points (color resolution) in one place.

README:
- Add a JSON-config section documenting the underlying `states`
  field name (the editor labels it "Values" but the node property
  is `states`, and several users have been caught by this when
  hand-editing flow JSON).
- Reword the "If a value is provided that it doesn't recognise"
  bullet to also cover the missing-color fallback.

No behaviour change for correctly-configured LEDs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant