Masks and zones improvements (#22163)

* migrator and runtime config changes

* component changes to use rasterized_mask

* frontend

* convert none to empty string for config save

* i18n

* update tests

* add enabled config to zones

* zones frontend

* i18n

* docs

* tweaks

* use dashed stroke to indicate disabled

* allow toggle from icon

* use filelock to ensure atomic config updates from endpoint

* enforce atomic config update in the frontend

* toggle via mqtt

* fix global object masks

* correctly handle global object masks in dispatcher

* ws hooks

* render masks and zones based on ws enabled state

* use enabled_in_config for zones and masks

* frontend for enabled_in_config

* tweaks

* i18n

* publish websocket on config save

* i18n tweaks

* pydantic title and description

* i18n generation

* tweaks

* fix typing
This commit is contained in:
Josh Hawkins
2026-02-28 07:04:43 -07:00
committed by GitHub
parent fa1f9a1fa4
commit 6a21b2952d
37 changed files with 1964 additions and 739 deletions
+11 -1
View File
@@ -24,6 +24,7 @@ type PolygonDrawerProps = {
isActive: boolean;
isHovered: boolean;
isFinished: boolean;
enabled?: boolean;
color: number[];
handlePointDragMove: (e: KonvaEventObject<MouseEvent | TouchEvent>) => void;
handleGroupDragEnd: (e: KonvaEventObject<MouseEvent | TouchEvent>) => void;
@@ -39,6 +40,7 @@ export default function PolygonDrawer({
isActive,
isHovered,
isFinished,
enabled = true,
color,
handlePointDragMove,
handleGroupDragEnd,
@@ -108,9 +110,15 @@ export default function PolygonDrawer({
const colorString = useCallback(
(darkened: boolean) => {
if (!enabled) {
// Slightly desaturate the color when disabled
const avg = (color[0] + color[1] + color[2]) / 3;
const desaturated = color.map((c) => Math.round(c * 0.4 + avg * 0.6));
return toRGBColorString(desaturated, darkened);
}
return toRGBColorString(color, darkened);
},
[color],
[color, enabled],
);
useEffect(() => {
@@ -162,9 +170,11 @@ export default function PolygonDrawer({
points={flattenedPoints}
stroke={colorString(true)}
strokeWidth={3}
dash={enabled ? undefined : [10, 5]}
hitStrokeWidth={12}
closed={isFinished}
fill={colorString(isActive || isHovered ? true : false)}
opacity={enabled ? 1 : 0.85}
onMouseOver={() =>
isActive
? isFinished