@camstack/ui-library 1.2.331 → 1.2.333
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{MotionZonesSettings-DR1g9ja3.js → MotionZonesSettings-BCU2NW7w.js} +1 -1
- package/dist/{PrivacyMaskSettings-C9wfHkiB.js → PrivacyMaskSettings-VntwpB1u.js} +1 -1
- package/dist/{SceneMonitorEditor-CrxB3ZPL.js → SceneMonitorEditor-5N2xqurW.js} +1 -1
- package/dist/composites/device-item/header.d.ts +7 -1
- package/dist/composites/device-name/DeviceName.d.ts +17 -0
- package/dist/composites/device-name/device-fleet.d.ts +29 -0
- package/dist/composites/device-name/device-name-nouns.d.ts +27 -0
- package/dist/composites/device-name/format-device-name.d.ts +46 -0
- package/dist/composites/device-name/index.d.ts +10 -0
- package/dist/composites/device-name/use-device-label.d.ts +16 -0
- package/dist/composites/grouped-tile-picker.d.ts +8 -11
- package/dist/composites/index.d.ts +1 -0
- package/dist/{icons-aFMzvquu.js → icons-Bd6sbDsv.js} +1 -35
- package/dist/{icons-pqV1UOV_.cjs → icons-CWmwnulO.cjs} +1 -35
- package/dist/index.cjs +1417 -89
- package/dist/index.js +1402 -95
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,7 @@ let react_dom_client = require("react-dom/client");
|
|
|
40
40
|
react_dom_client = __toESM(react_dom_client, 1);
|
|
41
41
|
let _trpc_client = require("@trpc/client");
|
|
42
42
|
_trpc_client = __toESM(_trpc_client, 1);
|
|
43
|
+
let _camstack_types_client = require("@camstack/types/client");
|
|
43
44
|
let _camstack_sdk = require("@camstack/sdk");
|
|
44
45
|
let zod = require("zod");
|
|
45
46
|
//#region src/contexts/ui-text.tsx
|
|
@@ -4706,6 +4707,40 @@ var VolumeX = require_createLucideIcon.createLucideIcon("volume-x", [
|
|
|
4706
4707
|
* This source code is licensed under the ISC license.
|
|
4707
4708
|
* See the LICENSE file in the root directory of this source tree.
|
|
4708
4709
|
*/
|
|
4710
|
+
var WashingMachine = require_createLucideIcon.createLucideIcon("washing-machine", [
|
|
4711
|
+
["path", {
|
|
4712
|
+
d: "M3 6h3",
|
|
4713
|
+
key: "155dbl"
|
|
4714
|
+
}],
|
|
4715
|
+
["path", {
|
|
4716
|
+
d: "M17 6h.01",
|
|
4717
|
+
key: "e2y6kg"
|
|
4718
|
+
}],
|
|
4719
|
+
["rect", {
|
|
4720
|
+
width: "18",
|
|
4721
|
+
height: "20",
|
|
4722
|
+
x: "3",
|
|
4723
|
+
y: "2",
|
|
4724
|
+
rx: "2",
|
|
4725
|
+
key: "od3kk9"
|
|
4726
|
+
}],
|
|
4727
|
+
["circle", {
|
|
4728
|
+
cx: "12",
|
|
4729
|
+
cy: "13",
|
|
4730
|
+
r: "5",
|
|
4731
|
+
key: "nlbqau"
|
|
4732
|
+
}],
|
|
4733
|
+
["path", {
|
|
4734
|
+
d: "M12 18a2.5 2.5 0 0 0 0-5 2.5 2.5 0 0 1 0-5",
|
|
4735
|
+
key: "17lach"
|
|
4736
|
+
}]
|
|
4737
|
+
]);
|
|
4738
|
+
/**
|
|
4739
|
+
* @license lucide-react v0.576.0 - ISC
|
|
4740
|
+
*
|
|
4741
|
+
* This source code is licensed under the ISC license.
|
|
4742
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
4743
|
+
*/
|
|
4709
4744
|
var Waves = require_createLucideIcon.createLucideIcon("waves", [
|
|
4710
4745
|
["path", {
|
|
4711
4746
|
d: "M2 6c.6.5 1.2 1 2.5 1C7 7 7 5 9.5 5c2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1",
|
|
@@ -5369,6 +5404,16 @@ var DEVICE_TYPE_META = {
|
|
|
5369
5404
|
icon: Waves,
|
|
5370
5405
|
labelKey: "uiLibrary.deviceMeta.type.dishwasher",
|
|
5371
5406
|
labelFallback: "Dishwasher"
|
|
5407
|
+
},
|
|
5408
|
+
[_camstack_types.DeviceType.Washer]: {
|
|
5409
|
+
icon: WashingMachine,
|
|
5410
|
+
labelKey: "uiLibrary.deviceMeta.type.washer",
|
|
5411
|
+
labelFallback: "Washing machine"
|
|
5412
|
+
},
|
|
5413
|
+
[_camstack_types.DeviceType.Dryer]: {
|
|
5414
|
+
icon: Wind,
|
|
5415
|
+
labelKey: "uiLibrary.deviceMeta.type.dryer",
|
|
5416
|
+
labelFallback: "Dryer"
|
|
5372
5417
|
}
|
|
5373
5418
|
};
|
|
5374
5419
|
var DEVICE_ROLE_META = {
|
|
@@ -5850,7 +5895,7 @@ function lucideExportName(key) {
|
|
|
5850
5895
|
function loadIconGlyphs() {
|
|
5851
5896
|
if (fullTable !== void 0) return Promise.resolve();
|
|
5852
5897
|
if (failure$1 !== void 0) return Promise.reject(failure$1);
|
|
5853
|
-
pending ??= Promise.resolve().then(() => require("./icons-
|
|
5898
|
+
pending ??= Promise.resolve().then(() => require("./icons-CWmwnulO.cjs")).then((module) => {
|
|
5854
5899
|
fullTable = module;
|
|
5855
5900
|
publish();
|
|
5856
5901
|
}, (error) => {
|
|
@@ -14504,6 +14549,9 @@ function AccountSignInField({ field, values, disabled, onAction, onChangeMany })
|
|
|
14504
14549
|
if (Object.keys(patch).length > 0) onChangeMany?.(patch);
|
|
14505
14550
|
const nextChoices = choicesOf(result["choices"]);
|
|
14506
14551
|
setChoices(nextChoices.length > 1 ? nextChoices : []);
|
|
14552
|
+
const picked = typeof result["gatewayId"] === "string" && result["gatewayId"].length > 0;
|
|
14553
|
+
const summary = typeof result["summary"] === "string" ? result["summary"] : null;
|
|
14554
|
+
if (summary !== null && !picked && nextChoices.length < 2) setError(summary);
|
|
14507
14555
|
setPhase("idle");
|
|
14508
14556
|
setPaste("");
|
|
14509
14557
|
setAttemptId(null);
|
|
@@ -19624,6 +19672,1151 @@ function AutotrackSection({ deviceId }) {
|
|
|
19624
19672
|
});
|
|
19625
19673
|
}
|
|
19626
19674
|
//#endregion
|
|
19675
|
+
//#region src/composites/device-name/device-fleet.tsx
|
|
19676
|
+
/**
|
|
19677
|
+
* One slim fleet, shared. A row reads its parent from this index — never a
|
|
19678
|
+
* `getDevice` per row (the Customize bounded-read rule). `null` is "not
|
|
19679
|
+
* answered yet": a label then keeps the stored name, so a list does not flash
|
|
19680
|
+
* `#id` while the fleet is in flight. An empty array is an answer.
|
|
19681
|
+
*/
|
|
19682
|
+
var DeviceNameIndexContext = (0, react$1.createContext)(null);
|
|
19683
|
+
function useDeviceNameIndex() {
|
|
19684
|
+
return (0, react$1.useContext)(DeviceNameIndexContext);
|
|
19685
|
+
}
|
|
19686
|
+
function copyDevice(device) {
|
|
19687
|
+
const label = device.display?.label;
|
|
19688
|
+
const trimmed = label === void 0 || label === null ? "" : label.trim();
|
|
19689
|
+
return {
|
|
19690
|
+
id: device.id,
|
|
19691
|
+
name: device.name,
|
|
19692
|
+
type: device.type,
|
|
19693
|
+
stableId: device.stableId,
|
|
19694
|
+
role: device.role ?? null,
|
|
19695
|
+
parentDeviceId: device.parentDeviceId ?? null,
|
|
19696
|
+
location: device.location ?? null,
|
|
19697
|
+
...trimmed.length > 0 ? { display: { label: trimmed } } : {},
|
|
19698
|
+
...device.primaryChildEntityId !== void 0 ? { primaryChildEntityId: device.primaryChildEntityId } : {},
|
|
19699
|
+
...device.userNamed === void 0 ? {} : { userNamed: device.userNamed }
|
|
19700
|
+
};
|
|
19701
|
+
}
|
|
19702
|
+
/** Build the parent/child maps once per fleet answer. */
|
|
19703
|
+
function indexDeviceNames(devices) {
|
|
19704
|
+
const byId = /* @__PURE__ */ new Map();
|
|
19705
|
+
const children = /* @__PURE__ */ new Map();
|
|
19706
|
+
for (const device of devices) {
|
|
19707
|
+
const fields = copyDevice(device);
|
|
19708
|
+
byId.set(fields.id, fields);
|
|
19709
|
+
const parentId = fields.parentDeviceId;
|
|
19710
|
+
if (parentId === null || parentId === void 0 || parentId === fields.id) continue;
|
|
19711
|
+
const list = children.get(parentId);
|
|
19712
|
+
if (list === void 0) children.set(parentId, [fields.id]);
|
|
19713
|
+
else list.push(fields.id);
|
|
19714
|
+
}
|
|
19715
|
+
return {
|
|
19716
|
+
byId,
|
|
19717
|
+
childIds: children
|
|
19718
|
+
};
|
|
19719
|
+
}
|
|
19720
|
+
function DeviceFleetProvider({ devices, children }) {
|
|
19721
|
+
const index = (0, react$1.useMemo)(() => devices === null ? null : indexDeviceNames(devices), [devices]);
|
|
19722
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceNameIndexContext.Provider, {
|
|
19723
|
+
value: index,
|
|
19724
|
+
children
|
|
19725
|
+
});
|
|
19726
|
+
}
|
|
19727
|
+
/**
|
|
19728
|
+
* The one `deviceManager.listAll` subscriber for names. Same query key the
|
|
19729
|
+
* pickers already use, so a second observer does not fetch a second fleet.
|
|
19730
|
+
*/
|
|
19731
|
+
function DeviceFleetFromServer({ children }) {
|
|
19732
|
+
const query = useDeviceManagerListAll({ projection: "slim" });
|
|
19733
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceFleetProvider, {
|
|
19734
|
+
devices: query.data === void 0 ? null : query.data,
|
|
19735
|
+
children
|
|
19736
|
+
});
|
|
19737
|
+
}
|
|
19738
|
+
//#endregion
|
|
19739
|
+
//#region src/composites/device-name/format-device-name.ts
|
|
19740
|
+
/**
|
|
19741
|
+
* One display name for a device.
|
|
19742
|
+
*
|
|
19743
|
+
* Canonical copy: `packages/ui-library/src/composites/device-name/format-device-name.ts`.
|
|
19744
|
+
* The viewer mirrors this file; `scripts/check-device-name-in-sync.ts` diffs the two.
|
|
19745
|
+
* Noun strings stay outside — this file only decides which noun to ask for.
|
|
19746
|
+
*/
|
|
19747
|
+
/** Middle dot used between a container and its noun, and before a room. */
|
|
19748
|
+
var DEVICE_NAME_JOIN = " · ";
|
|
19749
|
+
var DEVICE_NAME_FORMS = [
|
|
19750
|
+
"compact",
|
|
19751
|
+
"full",
|
|
19752
|
+
"nested",
|
|
19753
|
+
"with-location"
|
|
19754
|
+
];
|
|
19755
|
+
var PARENT_SEPARATORS = [" — ", " "];
|
|
19756
|
+
/**
|
|
19757
|
+
* Readings that are never what a container is. Matches the comment on
|
|
19758
|
+
* `CONTAINER_CHILD_ROLE_PRIORITY`: battery, temperature, humidity, illuminance,
|
|
19759
|
+
* signal, last-seen, plus numeric and enum. `update` is the same kind of row.
|
|
19760
|
+
*/
|
|
19761
|
+
var DIAGNOSTIC_ROLES = new Set([
|
|
19762
|
+
"battery-sensor",
|
|
19763
|
+
"temperature-sensor",
|
|
19764
|
+
"humidity-sensor",
|
|
19765
|
+
"ambient-light-sensor",
|
|
19766
|
+
"connectivity-sensor",
|
|
19767
|
+
"datetime-sensor",
|
|
19768
|
+
"numeric-sensor",
|
|
19769
|
+
"enum-sensor"
|
|
19770
|
+
]);
|
|
19771
|
+
/** Hyphen, underscore and whitespace fold together — the namesake comparison. */
|
|
19772
|
+
function foldDeviceName(value) {
|
|
19773
|
+
return value.toLowerCase().replace(/[-_\s]+/g, " ").trim();
|
|
19774
|
+
}
|
|
19775
|
+
function sameDeviceName(left, right) {
|
|
19776
|
+
return foldDeviceName(left) === foldDeviceName(right);
|
|
19777
|
+
}
|
|
19778
|
+
/**
|
|
19779
|
+
* Drop a parent prefix. `" — "` before a space, case-insensitive, so a provider
|
|
19780
|
+
* that capitalised the parent differently still strips, and an em-dash child
|
|
19781
|
+
* does not keep a dangling dash.
|
|
19782
|
+
*/
|
|
19783
|
+
function stripDeviceParentPrefix(name, parentName) {
|
|
19784
|
+
if (parentName.length === 0) return name;
|
|
19785
|
+
const nameFold = name.toLowerCase();
|
|
19786
|
+
const parentFold = parentName.toLowerCase();
|
|
19787
|
+
for (const separator of PARENT_SEPARATORS) {
|
|
19788
|
+
const prefix = `${parentFold}${separator}`;
|
|
19789
|
+
if (!nameFold.startsWith(prefix)) continue;
|
|
19790
|
+
return name.slice(prefix.length).trim();
|
|
19791
|
+
}
|
|
19792
|
+
return name;
|
|
19793
|
+
}
|
|
19794
|
+
function roleOf(device) {
|
|
19795
|
+
const role = device.role;
|
|
19796
|
+
if (role === void 0 || role === null || role.length === 0) return null;
|
|
19797
|
+
return role;
|
|
19798
|
+
}
|
|
19799
|
+
function isDiagnostic(device) {
|
|
19800
|
+
if (device.type === "update") return true;
|
|
19801
|
+
const role = roleOf(device);
|
|
19802
|
+
return role !== null && DIAGNOSTIC_ROLES.has(role);
|
|
19803
|
+
}
|
|
19804
|
+
function displayLabel(device) {
|
|
19805
|
+
const label = device.display?.label;
|
|
19806
|
+
if (label === void 0 || label === null) return "";
|
|
19807
|
+
return label.trim();
|
|
19808
|
+
}
|
|
19809
|
+
function nounOf(device, parent, nouns) {
|
|
19810
|
+
const caption = displayLabel(device);
|
|
19811
|
+
if (caption.length > 0) return caption;
|
|
19812
|
+
const stripped = stripDeviceParentPrefix(device.name, parent.name);
|
|
19813
|
+
const shown = stripped.length > 0 ? stripped : device.name;
|
|
19814
|
+
if (device.userNamed === true) return shown;
|
|
19815
|
+
if (stripped.length === 0 || sameDeviceName(stripped, parent.name) || nouns.isStockPhrase(shown, roleOf(device), device.type)) return nouns.shortNoun(roleOf(device), device.type);
|
|
19816
|
+
return shown;
|
|
19817
|
+
}
|
|
19818
|
+
function foldsIntoParent(device, parent, noun) {
|
|
19819
|
+
if (sameDeviceName(noun, parent.name)) return true;
|
|
19820
|
+
if (displayLabel(device).length > 0 || device.userNamed === true) return false;
|
|
19821
|
+
return sameDeviceName(stripDeviceParentPrefix(device.name, parent.name), parent.name);
|
|
19822
|
+
}
|
|
19823
|
+
function meaningfulChildCount(siblings) {
|
|
19824
|
+
let count = 0;
|
|
19825
|
+
for (const sibling of siblings) if (!isDiagnostic(sibling)) count += 1;
|
|
19826
|
+
return count;
|
|
19827
|
+
}
|
|
19828
|
+
function isContainerPrimary(device, parent, siblings) {
|
|
19829
|
+
const picked = (0, _camstack_types_client.resolveContainerPrimaryChild)(siblings.map((sibling) => {
|
|
19830
|
+
const role = roleOf(sibling);
|
|
19831
|
+
return {
|
|
19832
|
+
id: sibling.id,
|
|
19833
|
+
stableId: sibling.stableId,
|
|
19834
|
+
type: sibling.type,
|
|
19835
|
+
name: sibling.name,
|
|
19836
|
+
...role === null ? {} : { role }
|
|
19837
|
+
};
|
|
19838
|
+
}), parent.primaryChildEntityId, parent.name);
|
|
19839
|
+
return picked !== null && picked.id === device.id;
|
|
19840
|
+
}
|
|
19841
|
+
function childLine(device, parent, siblings, nouns, form) {
|
|
19842
|
+
const noun = nounOf(device, parent, nouns);
|
|
19843
|
+
if (foldsIntoParent(device, parent, noun)) return parent.name;
|
|
19844
|
+
if (form === "compact" && parent.type === "container" && isContainerPrimary(device, parent, siblings) && meaningfulChildCount(siblings) === 1) return parent.name;
|
|
19845
|
+
return `${parent.name}${DEVICE_NAME_JOIN}${noun}`;
|
|
19846
|
+
}
|
|
19847
|
+
function joinLocation(label, location) {
|
|
19848
|
+
if (location === void 0 || location === null) return label;
|
|
19849
|
+
const room = location.trim();
|
|
19850
|
+
if (room.length === 0) return label;
|
|
19851
|
+
if (label.split(" · ").some((segment) => sameDeviceName(segment, room))) return label;
|
|
19852
|
+
return `${label}${DEVICE_NAME_JOIN}${room}`;
|
|
19853
|
+
}
|
|
19854
|
+
function hasParent(device, parent) {
|
|
19855
|
+
if (parent === null) return false;
|
|
19856
|
+
const parentId = device.parentDeviceId;
|
|
19857
|
+
return parentId !== null && parentId !== void 0;
|
|
19858
|
+
}
|
|
19859
|
+
/**
|
|
19860
|
+
* The label for `form`. A top-level device keeps its stored name. A child uses
|
|
19861
|
+
* the noun: `compact` may stand in for the container when this child is what
|
|
19862
|
+
* the container is, `full` always names both unless they fold together,
|
|
19863
|
+
* `nested` is the noun alone, `with-location` is `compact` plus the room.
|
|
19864
|
+
*/
|
|
19865
|
+
function formatDeviceName(device, form, context, nouns) {
|
|
19866
|
+
if (!hasParent(device, context.parent)) return form === "with-location" ? joinLocation(device.name, device.location) : device.name;
|
|
19867
|
+
if (form === "nested") return nounOf(device, context.parent, nouns);
|
|
19868
|
+
const line = childLine(device, context.parent, context.siblings, nouns, form === "full" ? "full" : "compact");
|
|
19869
|
+
return form === "with-location" ? joinLocation(line, device.location) : line;
|
|
19870
|
+
}
|
|
19871
|
+
//#endregion
|
|
19872
|
+
//#region src/composites/device-name/device-name-nouns.ts
|
|
19873
|
+
/**
|
|
19874
|
+
* Short nouns and the stock words they replace.
|
|
19875
|
+
*
|
|
19876
|
+
* Long labels are the existing role and type names, both locales, so a stored
|
|
19877
|
+
* "Motion sensor" and a stored "Sensore di movimento" are the same stock word.
|
|
19878
|
+
* The short noun is what a list shows. Where the long label is already one
|
|
19879
|
+
* word it is the short noun. Aliases are provider stock words that are not the
|
|
19880
|
+
* label ("Illumination", "Last seen").
|
|
19881
|
+
*/
|
|
19882
|
+
var DEVICE_ROLE_NOUNS = [
|
|
19883
|
+
{
|
|
19884
|
+
id: "siren",
|
|
19885
|
+
key: "uiLibrary.deviceMeta.noun.role.siren",
|
|
19886
|
+
en: "Siren",
|
|
19887
|
+
it: "Sirena",
|
|
19888
|
+
shortEn: "Siren",
|
|
19889
|
+
shortIt: "Sirena",
|
|
19890
|
+
aliases: []
|
|
19891
|
+
},
|
|
19892
|
+
{
|
|
19893
|
+
id: "floodlight",
|
|
19894
|
+
key: "uiLibrary.deviceMeta.noun.role.floodlight",
|
|
19895
|
+
en: "Floodlight",
|
|
19896
|
+
it: "Faro",
|
|
19897
|
+
shortEn: "Floodlight",
|
|
19898
|
+
shortIt: "Faro",
|
|
19899
|
+
aliases: []
|
|
19900
|
+
},
|
|
19901
|
+
{
|
|
19902
|
+
id: "spotlight",
|
|
19903
|
+
key: "uiLibrary.deviceMeta.noun.role.spotlight",
|
|
19904
|
+
en: "Spotlight",
|
|
19905
|
+
it: "Faretto",
|
|
19906
|
+
shortEn: "Spotlight",
|
|
19907
|
+
shortIt: "Faretto",
|
|
19908
|
+
aliases: []
|
|
19909
|
+
},
|
|
19910
|
+
{
|
|
19911
|
+
id: "pir-sensor",
|
|
19912
|
+
key: "uiLibrary.deviceMeta.noun.role.pirSensor",
|
|
19913
|
+
en: "PIR sensor",
|
|
19914
|
+
it: "Sensore PIR",
|
|
19915
|
+
shortEn: "PIR",
|
|
19916
|
+
shortIt: "PIR",
|
|
19917
|
+
aliases: []
|
|
19918
|
+
},
|
|
19919
|
+
{
|
|
19920
|
+
id: "chime",
|
|
19921
|
+
key: "uiLibrary.deviceMeta.noun.role.chime",
|
|
19922
|
+
en: "Chime",
|
|
19923
|
+
it: "Campanello",
|
|
19924
|
+
shortEn: "Chime",
|
|
19925
|
+
shortIt: "Campanello",
|
|
19926
|
+
aliases: []
|
|
19927
|
+
},
|
|
19928
|
+
{
|
|
19929
|
+
id: "autotrack",
|
|
19930
|
+
key: "uiLibrary.deviceMeta.noun.role.autotrack",
|
|
19931
|
+
en: "Auto-track",
|
|
19932
|
+
it: "Auto-tracking",
|
|
19933
|
+
shortEn: "Auto-track",
|
|
19934
|
+
shortIt: "Auto-tracking",
|
|
19935
|
+
aliases: []
|
|
19936
|
+
},
|
|
19937
|
+
{
|
|
19938
|
+
id: "nightvision",
|
|
19939
|
+
key: "uiLibrary.deviceMeta.noun.role.nightvision",
|
|
19940
|
+
en: "Night vision",
|
|
19941
|
+
it: "Visione notturna",
|
|
19942
|
+
shortEn: "Night",
|
|
19943
|
+
shortIt: "Notturna",
|
|
19944
|
+
aliases: []
|
|
19945
|
+
},
|
|
19946
|
+
{
|
|
19947
|
+
id: "privacy-mask",
|
|
19948
|
+
key: "uiLibrary.deviceMeta.noun.role.privacyMask",
|
|
19949
|
+
en: "Privacy mask",
|
|
19950
|
+
it: "Maschera privacy",
|
|
19951
|
+
shortEn: "Privacy",
|
|
19952
|
+
shortIt: "Privacy",
|
|
19953
|
+
aliases: []
|
|
19954
|
+
},
|
|
19955
|
+
{
|
|
19956
|
+
id: "doorbell",
|
|
19957
|
+
key: "uiLibrary.deviceMeta.noun.role.doorbell",
|
|
19958
|
+
en: "Doorbell",
|
|
19959
|
+
it: "Campanello video",
|
|
19960
|
+
shortEn: "Doorbell",
|
|
19961
|
+
shortIt: "Campanello video",
|
|
19962
|
+
aliases: []
|
|
19963
|
+
},
|
|
19964
|
+
{
|
|
19965
|
+
id: "cover-blind",
|
|
19966
|
+
key: "uiLibrary.deviceMeta.noun.role.coverBlind",
|
|
19967
|
+
en: "Blind",
|
|
19968
|
+
it: "Tapparella",
|
|
19969
|
+
shortEn: "Blind",
|
|
19970
|
+
shortIt: "Tapparella",
|
|
19971
|
+
aliases: []
|
|
19972
|
+
},
|
|
19973
|
+
{
|
|
19974
|
+
id: "cover-shutter",
|
|
19975
|
+
key: "uiLibrary.deviceMeta.noun.role.coverShutter",
|
|
19976
|
+
en: "Shutter",
|
|
19977
|
+
it: "Persiana",
|
|
19978
|
+
shortEn: "Shutter",
|
|
19979
|
+
shortIt: "Persiana",
|
|
19980
|
+
aliases: []
|
|
19981
|
+
},
|
|
19982
|
+
{
|
|
19983
|
+
id: "cover-awning",
|
|
19984
|
+
key: "uiLibrary.deviceMeta.noun.role.coverAwning",
|
|
19985
|
+
en: "Awning",
|
|
19986
|
+
it: "Tenda da sole",
|
|
19987
|
+
shortEn: "Awning",
|
|
19988
|
+
shortIt: "Tenda da sole",
|
|
19989
|
+
aliases: []
|
|
19990
|
+
},
|
|
19991
|
+
{
|
|
19992
|
+
id: "cover-curtain",
|
|
19993
|
+
key: "uiLibrary.deviceMeta.noun.role.coverCurtain",
|
|
19994
|
+
en: "Curtain",
|
|
19995
|
+
it: "Tenda",
|
|
19996
|
+
shortEn: "Curtain",
|
|
19997
|
+
shortIt: "Tenda",
|
|
19998
|
+
aliases: []
|
|
19999
|
+
},
|
|
20000
|
+
{
|
|
20001
|
+
id: "cover-garage",
|
|
20002
|
+
key: "uiLibrary.deviceMeta.noun.role.coverGarage",
|
|
20003
|
+
en: "Garage door",
|
|
20004
|
+
it: "Porta del garage",
|
|
20005
|
+
shortEn: "Garage",
|
|
20006
|
+
shortIt: "Garage",
|
|
20007
|
+
aliases: []
|
|
20008
|
+
},
|
|
20009
|
+
{
|
|
20010
|
+
id: "cover-gate",
|
|
20011
|
+
key: "uiLibrary.deviceMeta.noun.role.coverGate",
|
|
20012
|
+
en: "Gate",
|
|
20013
|
+
it: "Cancello",
|
|
20014
|
+
shortEn: "Gate",
|
|
20015
|
+
shortIt: "Cancello",
|
|
20016
|
+
aliases: []
|
|
20017
|
+
},
|
|
20018
|
+
{
|
|
20019
|
+
id: "cover-door",
|
|
20020
|
+
key: "uiLibrary.deviceMeta.noun.role.coverDoor",
|
|
20021
|
+
en: "Door",
|
|
20022
|
+
it: "Porta",
|
|
20023
|
+
shortEn: "Door",
|
|
20024
|
+
shortIt: "Porta",
|
|
20025
|
+
aliases: []
|
|
20026
|
+
},
|
|
20027
|
+
{
|
|
20028
|
+
id: "cover-window",
|
|
20029
|
+
key: "uiLibrary.deviceMeta.noun.role.coverWindow",
|
|
20030
|
+
en: "Window",
|
|
20031
|
+
it: "Finestra",
|
|
20032
|
+
shortEn: "Window",
|
|
20033
|
+
shortIt: "Finestra",
|
|
20034
|
+
aliases: []
|
|
20035
|
+
},
|
|
20036
|
+
{
|
|
20037
|
+
id: "binary-helper",
|
|
20038
|
+
key: "uiLibrary.deviceMeta.noun.role.binaryHelper",
|
|
20039
|
+
en: "Binary helper",
|
|
20040
|
+
it: "Helper binario",
|
|
20041
|
+
shortEn: "Helper",
|
|
20042
|
+
shortIt: "Helper",
|
|
20043
|
+
aliases: []
|
|
20044
|
+
},
|
|
20045
|
+
{
|
|
20046
|
+
id: "outlet",
|
|
20047
|
+
key: "uiLibrary.deviceMeta.noun.role.outlet",
|
|
20048
|
+
en: "Outlet",
|
|
20049
|
+
it: "Presa",
|
|
20050
|
+
shortEn: "Outlet",
|
|
20051
|
+
shortIt: "Presa",
|
|
20052
|
+
aliases: []
|
|
20053
|
+
},
|
|
20054
|
+
{
|
|
20055
|
+
id: "motion-sensor",
|
|
20056
|
+
key: "uiLibrary.deviceMeta.noun.role.motionSensor",
|
|
20057
|
+
en: "Motion sensor",
|
|
20058
|
+
it: "Sensore di movimento",
|
|
20059
|
+
shortEn: "Motion",
|
|
20060
|
+
shortIt: "Movimento",
|
|
20061
|
+
aliases: []
|
|
20062
|
+
},
|
|
20063
|
+
{
|
|
20064
|
+
id: "contact-sensor",
|
|
20065
|
+
key: "uiLibrary.deviceMeta.noun.role.contactSensor",
|
|
20066
|
+
en: "Contact sensor",
|
|
20067
|
+
it: "Sensore di contatto",
|
|
20068
|
+
shortEn: "Contact",
|
|
20069
|
+
shortIt: "Contatto",
|
|
20070
|
+
aliases: []
|
|
20071
|
+
},
|
|
20072
|
+
{
|
|
20073
|
+
id: "leak-sensor",
|
|
20074
|
+
key: "uiLibrary.deviceMeta.noun.role.leakSensor",
|
|
20075
|
+
en: "Leak sensor",
|
|
20076
|
+
it: "Sensore di perdite",
|
|
20077
|
+
shortEn: "Leak",
|
|
20078
|
+
shortIt: "Perdita",
|
|
20079
|
+
aliases: []
|
|
20080
|
+
},
|
|
20081
|
+
{
|
|
20082
|
+
id: "smoke-sensor",
|
|
20083
|
+
key: "uiLibrary.deviceMeta.noun.role.smokeSensor",
|
|
20084
|
+
en: "Smoke sensor",
|
|
20085
|
+
it: "Sensore di fumo",
|
|
20086
|
+
shortEn: "Smoke",
|
|
20087
|
+
shortIt: "Fumo",
|
|
20088
|
+
aliases: []
|
|
20089
|
+
},
|
|
20090
|
+
{
|
|
20091
|
+
id: "co-sensor",
|
|
20092
|
+
key: "uiLibrary.deviceMeta.noun.role.cOSensor",
|
|
20093
|
+
en: "CO sensor",
|
|
20094
|
+
it: "Sensore di CO",
|
|
20095
|
+
shortEn: "CO",
|
|
20096
|
+
shortIt: "CO",
|
|
20097
|
+
aliases: []
|
|
20098
|
+
},
|
|
20099
|
+
{
|
|
20100
|
+
id: "gas-sensor",
|
|
20101
|
+
key: "uiLibrary.deviceMeta.noun.role.gasSensor",
|
|
20102
|
+
en: "Gas sensor",
|
|
20103
|
+
it: "Sensore di gas",
|
|
20104
|
+
shortEn: "Gas",
|
|
20105
|
+
shortIt: "Gas",
|
|
20106
|
+
aliases: []
|
|
20107
|
+
},
|
|
20108
|
+
{
|
|
20109
|
+
id: "tamper-sensor",
|
|
20110
|
+
key: "uiLibrary.deviceMeta.noun.role.tamperSensor",
|
|
20111
|
+
en: "Tamper sensor",
|
|
20112
|
+
it: "Sensore antimanomissione",
|
|
20113
|
+
shortEn: "Tamper",
|
|
20114
|
+
shortIt: "Manomissione",
|
|
20115
|
+
aliases: []
|
|
20116
|
+
},
|
|
20117
|
+
{
|
|
20118
|
+
id: "vibration-sensor",
|
|
20119
|
+
key: "uiLibrary.deviceMeta.noun.role.vibrationSensor",
|
|
20120
|
+
en: "Vibration sensor",
|
|
20121
|
+
it: "Sensore di vibrazione",
|
|
20122
|
+
shortEn: "Vibration",
|
|
20123
|
+
shortIt: "Vibrazione",
|
|
20124
|
+
aliases: []
|
|
20125
|
+
},
|
|
20126
|
+
{
|
|
20127
|
+
id: "connectivity-sensor",
|
|
20128
|
+
key: "uiLibrary.deviceMeta.noun.role.connectivitySensor",
|
|
20129
|
+
en: "Connectivity",
|
|
20130
|
+
it: "Connettività",
|
|
20131
|
+
shortEn: "Connectivity",
|
|
20132
|
+
shortIt: "Connettività",
|
|
20133
|
+
aliases: []
|
|
20134
|
+
},
|
|
20135
|
+
{
|
|
20136
|
+
id: "sound-sensor",
|
|
20137
|
+
key: "uiLibrary.deviceMeta.noun.role.soundSensor",
|
|
20138
|
+
en: "Sound sensor",
|
|
20139
|
+
it: "Sensore acustico",
|
|
20140
|
+
shortEn: "Sound",
|
|
20141
|
+
shortIt: "Suono",
|
|
20142
|
+
aliases: []
|
|
20143
|
+
},
|
|
20144
|
+
{
|
|
20145
|
+
id: "binary-sensor",
|
|
20146
|
+
key: "uiLibrary.deviceMeta.noun.role.binarySensor",
|
|
20147
|
+
en: "Binary sensor",
|
|
20148
|
+
it: "Sensore binario",
|
|
20149
|
+
shortEn: "Binary",
|
|
20150
|
+
shortIt: "Binario",
|
|
20151
|
+
aliases: []
|
|
20152
|
+
},
|
|
20153
|
+
{
|
|
20154
|
+
id: "temperature-sensor",
|
|
20155
|
+
key: "uiLibrary.deviceMeta.noun.role.temperatureSensor",
|
|
20156
|
+
en: "Temperature",
|
|
20157
|
+
it: "Temperatura",
|
|
20158
|
+
shortEn: "Temperature",
|
|
20159
|
+
shortIt: "Temperatura",
|
|
20160
|
+
aliases: []
|
|
20161
|
+
},
|
|
20162
|
+
{
|
|
20163
|
+
id: "humidity-sensor",
|
|
20164
|
+
key: "uiLibrary.deviceMeta.noun.role.humiditySensor",
|
|
20165
|
+
en: "Humidity",
|
|
20166
|
+
it: "Umidità",
|
|
20167
|
+
shortEn: "Humidity",
|
|
20168
|
+
shortIt: "Umidità",
|
|
20169
|
+
aliases: []
|
|
20170
|
+
},
|
|
20171
|
+
{
|
|
20172
|
+
id: "ambient-light-sensor",
|
|
20173
|
+
key: "uiLibrary.deviceMeta.noun.role.ambientLightSensor",
|
|
20174
|
+
en: "Ambient light",
|
|
20175
|
+
it: "Luce ambientale",
|
|
20176
|
+
shortEn: "Light",
|
|
20177
|
+
shortIt: "Luce",
|
|
20178
|
+
aliases: ["Illumination"]
|
|
20179
|
+
},
|
|
20180
|
+
{
|
|
20181
|
+
id: "pressure-sensor",
|
|
20182
|
+
key: "uiLibrary.deviceMeta.noun.role.pressureSensor",
|
|
20183
|
+
en: "Pressure",
|
|
20184
|
+
it: "Pressione",
|
|
20185
|
+
shortEn: "Pressure",
|
|
20186
|
+
shortIt: "Pressione",
|
|
20187
|
+
aliases: []
|
|
20188
|
+
},
|
|
20189
|
+
{
|
|
20190
|
+
id: "wind-sensor",
|
|
20191
|
+
key: "uiLibrary.deviceMeta.noun.role.windSensor",
|
|
20192
|
+
en: "Wind",
|
|
20193
|
+
it: "Vento",
|
|
20194
|
+
shortEn: "Wind",
|
|
20195
|
+
shortIt: "Vento",
|
|
20196
|
+
aliases: []
|
|
20197
|
+
},
|
|
20198
|
+
{
|
|
20199
|
+
id: "rain-sensor",
|
|
20200
|
+
key: "uiLibrary.deviceMeta.noun.role.rainSensor",
|
|
20201
|
+
en: "Rain",
|
|
20202
|
+
it: "Pioggia",
|
|
20203
|
+
shortEn: "Rain",
|
|
20204
|
+
shortIt: "Pioggia",
|
|
20205
|
+
aliases: []
|
|
20206
|
+
},
|
|
20207
|
+
{
|
|
20208
|
+
id: "uv-sensor",
|
|
20209
|
+
key: "uiLibrary.deviceMeta.noun.role.uvSensor",
|
|
20210
|
+
en: "UV index",
|
|
20211
|
+
it: "Indice UV",
|
|
20212
|
+
shortEn: "UV index",
|
|
20213
|
+
shortIt: "Indice UV",
|
|
20214
|
+
aliases: []
|
|
20215
|
+
},
|
|
20216
|
+
{
|
|
20217
|
+
id: "solar-radiation-sensor",
|
|
20218
|
+
key: "uiLibrary.deviceMeta.noun.role.solarRadiationSensor",
|
|
20219
|
+
en: "Solar radiation",
|
|
20220
|
+
it: "Radiazione solare",
|
|
20221
|
+
shortEn: "Solar radiation",
|
|
20222
|
+
shortIt: "Radiazione solare",
|
|
20223
|
+
aliases: []
|
|
20224
|
+
},
|
|
20225
|
+
{
|
|
20226
|
+
id: "soil-moisture-sensor",
|
|
20227
|
+
key: "uiLibrary.deviceMeta.noun.role.soilMoistureSensor",
|
|
20228
|
+
en: "Soil moisture",
|
|
20229
|
+
it: "Umidità del suolo",
|
|
20230
|
+
shortEn: "Soil moisture",
|
|
20231
|
+
shortIt: "Umidità del suolo",
|
|
20232
|
+
aliases: []
|
|
20233
|
+
},
|
|
20234
|
+
{
|
|
20235
|
+
id: "power-sensor",
|
|
20236
|
+
key: "uiLibrary.deviceMeta.noun.role.powerSensor",
|
|
20237
|
+
en: "Power",
|
|
20238
|
+
it: "Potenza",
|
|
20239
|
+
shortEn: "Power",
|
|
20240
|
+
shortIt: "Potenza",
|
|
20241
|
+
aliases: []
|
|
20242
|
+
},
|
|
20243
|
+
{
|
|
20244
|
+
id: "energy-sensor",
|
|
20245
|
+
key: "uiLibrary.deviceMeta.noun.role.energySensor",
|
|
20246
|
+
en: "Energy",
|
|
20247
|
+
it: "Energia",
|
|
20248
|
+
shortEn: "Energy",
|
|
20249
|
+
shortIt: "Energia",
|
|
20250
|
+
aliases: []
|
|
20251
|
+
},
|
|
20252
|
+
{
|
|
20253
|
+
id: "voltage-sensor",
|
|
20254
|
+
key: "uiLibrary.deviceMeta.noun.role.voltageSensor",
|
|
20255
|
+
en: "Voltage",
|
|
20256
|
+
it: "Tensione",
|
|
20257
|
+
shortEn: "Voltage",
|
|
20258
|
+
shortIt: "Tensione",
|
|
20259
|
+
aliases: []
|
|
20260
|
+
},
|
|
20261
|
+
{
|
|
20262
|
+
id: "current-sensor",
|
|
20263
|
+
key: "uiLibrary.deviceMeta.noun.role.currentSensor",
|
|
20264
|
+
en: "Current",
|
|
20265
|
+
it: "Corrente",
|
|
20266
|
+
shortEn: "Current",
|
|
20267
|
+
shortIt: "Corrente",
|
|
20268
|
+
aliases: []
|
|
20269
|
+
},
|
|
20270
|
+
{
|
|
20271
|
+
id: "air-quality-sensor",
|
|
20272
|
+
key: "uiLibrary.deviceMeta.noun.role.airQualitySensor",
|
|
20273
|
+
en: "Air quality",
|
|
20274
|
+
it: "Qualità dell’aria",
|
|
20275
|
+
shortEn: "Air quality",
|
|
20276
|
+
shortIt: "Qualità dell’aria",
|
|
20277
|
+
aliases: []
|
|
20278
|
+
},
|
|
20279
|
+
{
|
|
20280
|
+
id: "battery-sensor",
|
|
20281
|
+
key: "uiLibrary.deviceMeta.noun.role.batterySensor",
|
|
20282
|
+
en: "Battery",
|
|
20283
|
+
it: "Batteria",
|
|
20284
|
+
shortEn: "Battery",
|
|
20285
|
+
shortIt: "Batteria",
|
|
20286
|
+
aliases: []
|
|
20287
|
+
},
|
|
20288
|
+
{
|
|
20289
|
+
id: "numeric-sensor",
|
|
20290
|
+
key: "uiLibrary.deviceMeta.noun.role.numericSensor",
|
|
20291
|
+
en: "Numeric sensor",
|
|
20292
|
+
it: "Sensore numerico",
|
|
20293
|
+
shortEn: "Value",
|
|
20294
|
+
shortIt: "Numerico",
|
|
20295
|
+
aliases: []
|
|
20296
|
+
},
|
|
20297
|
+
{
|
|
20298
|
+
id: "enum-sensor",
|
|
20299
|
+
key: "uiLibrary.deviceMeta.noun.role.enumSensor",
|
|
20300
|
+
en: "Enum sensor",
|
|
20301
|
+
it: "Sensore a stati",
|
|
20302
|
+
shortEn: "State",
|
|
20303
|
+
shortIt: "Stato",
|
|
20304
|
+
aliases: []
|
|
20305
|
+
},
|
|
20306
|
+
{
|
|
20307
|
+
id: "datetime-sensor",
|
|
20308
|
+
key: "uiLibrary.deviceMeta.noun.role.dateTimeSensor",
|
|
20309
|
+
en: "Date / time",
|
|
20310
|
+
it: "Data / ora",
|
|
20311
|
+
shortEn: "Time",
|
|
20312
|
+
shortIt: "Ora",
|
|
20313
|
+
aliases: ["Last seen"]
|
|
20314
|
+
},
|
|
20315
|
+
{
|
|
20316
|
+
id: "generic-sensor",
|
|
20317
|
+
key: "uiLibrary.deviceMeta.noun.role.genericSensor",
|
|
20318
|
+
en: "Sensor",
|
|
20319
|
+
it: "Sensore",
|
|
20320
|
+
shortEn: "Sensor",
|
|
20321
|
+
shortIt: "Sensore",
|
|
20322
|
+
aliases: []
|
|
20323
|
+
},
|
|
20324
|
+
{
|
|
20325
|
+
id: "numeric-control",
|
|
20326
|
+
key: "uiLibrary.deviceMeta.noun.role.numericControl",
|
|
20327
|
+
en: "Numeric control",
|
|
20328
|
+
it: "Controllo numerico",
|
|
20329
|
+
shortEn: "Number",
|
|
20330
|
+
shortIt: "Numero",
|
|
20331
|
+
aliases: []
|
|
20332
|
+
},
|
|
20333
|
+
{
|
|
20334
|
+
id: "select-control",
|
|
20335
|
+
key: "uiLibrary.deviceMeta.noun.role.selectControl",
|
|
20336
|
+
en: "Select control",
|
|
20337
|
+
it: "Controllo a selezione",
|
|
20338
|
+
shortEn: "Select",
|
|
20339
|
+
shortIt: "Selezione",
|
|
20340
|
+
aliases: []
|
|
20341
|
+
},
|
|
20342
|
+
{
|
|
20343
|
+
id: "text-control",
|
|
20344
|
+
key: "uiLibrary.deviceMeta.noun.role.textControl",
|
|
20345
|
+
en: "Text control",
|
|
20346
|
+
it: "Controllo testo",
|
|
20347
|
+
shortEn: "Text",
|
|
20348
|
+
shortIt: "Testo",
|
|
20349
|
+
aliases: []
|
|
20350
|
+
},
|
|
20351
|
+
{
|
|
20352
|
+
id: "datetime-control",
|
|
20353
|
+
key: "uiLibrary.deviceMeta.noun.role.dateTimeControl",
|
|
20354
|
+
en: "Date / time control",
|
|
20355
|
+
it: "Controllo data / ora",
|
|
20356
|
+
shortEn: "Time",
|
|
20357
|
+
shortIt: "Ora",
|
|
20358
|
+
aliases: []
|
|
20359
|
+
},
|
|
20360
|
+
{
|
|
20361
|
+
id: "mobile-push-notifier",
|
|
20362
|
+
key: "uiLibrary.deviceMeta.noun.role.mobilePushNotifier",
|
|
20363
|
+
en: "Mobile push",
|
|
20364
|
+
it: "Push su mobile",
|
|
20365
|
+
shortEn: "Push",
|
|
20366
|
+
shortIt: "Push",
|
|
20367
|
+
aliases: []
|
|
20368
|
+
},
|
|
20369
|
+
{
|
|
20370
|
+
id: "messaging-notifier",
|
|
20371
|
+
key: "uiLibrary.deviceMeta.noun.role.messagingNotifier",
|
|
20372
|
+
en: "Messaging",
|
|
20373
|
+
it: "Messaggistica",
|
|
20374
|
+
shortEn: "Messaging",
|
|
20375
|
+
shortIt: "Messaggistica",
|
|
20376
|
+
aliases: []
|
|
20377
|
+
},
|
|
20378
|
+
{
|
|
20379
|
+
id: "email-notifier",
|
|
20380
|
+
key: "uiLibrary.deviceMeta.noun.role.emailNotifier",
|
|
20381
|
+
en: "Email",
|
|
20382
|
+
it: "Email",
|
|
20383
|
+
shortEn: "Email",
|
|
20384
|
+
shortIt: "Email",
|
|
20385
|
+
aliases: []
|
|
20386
|
+
},
|
|
20387
|
+
{
|
|
20388
|
+
id: "generic-notifier",
|
|
20389
|
+
key: "uiLibrary.deviceMeta.noun.role.genericNotifier",
|
|
20390
|
+
en: "Notifier",
|
|
20391
|
+
it: "Notificatore",
|
|
20392
|
+
shortEn: "Notifier",
|
|
20393
|
+
shortIt: "Notificatore",
|
|
20394
|
+
aliases: []
|
|
20395
|
+
}
|
|
20396
|
+
];
|
|
20397
|
+
var DEVICE_TYPE_NOUNS = [
|
|
20398
|
+
{
|
|
20399
|
+
id: "camera",
|
|
20400
|
+
key: "uiLibrary.deviceMeta.noun.type.camera",
|
|
20401
|
+
en: "Camera",
|
|
20402
|
+
it: "Telecamera",
|
|
20403
|
+
shortEn: "Camera",
|
|
20404
|
+
shortIt: "Telecamera",
|
|
20405
|
+
aliases: []
|
|
20406
|
+
},
|
|
20407
|
+
{
|
|
20408
|
+
id: "hub",
|
|
20409
|
+
key: "uiLibrary.deviceMeta.noun.type.hub",
|
|
20410
|
+
en: "Hub",
|
|
20411
|
+
it: "Hub",
|
|
20412
|
+
shortEn: "Hub",
|
|
20413
|
+
shortIt: "Hub",
|
|
20414
|
+
aliases: []
|
|
20415
|
+
},
|
|
20416
|
+
{
|
|
20417
|
+
id: "light",
|
|
20418
|
+
key: "uiLibrary.deviceMeta.noun.type.light",
|
|
20419
|
+
en: "Light",
|
|
20420
|
+
it: "Luce",
|
|
20421
|
+
shortEn: "Light",
|
|
20422
|
+
shortIt: "Luce",
|
|
20423
|
+
aliases: []
|
|
20424
|
+
},
|
|
20425
|
+
{
|
|
20426
|
+
id: "siren",
|
|
20427
|
+
key: "uiLibrary.deviceMeta.noun.type.siren",
|
|
20428
|
+
en: "Siren",
|
|
20429
|
+
it: "Sirena",
|
|
20430
|
+
shortEn: "Siren",
|
|
20431
|
+
shortIt: "Sirena",
|
|
20432
|
+
aliases: []
|
|
20433
|
+
},
|
|
20434
|
+
{
|
|
20435
|
+
id: "switch",
|
|
20436
|
+
key: "uiLibrary.deviceMeta.noun.type.switch",
|
|
20437
|
+
en: "Switch",
|
|
20438
|
+
it: "Interruttore",
|
|
20439
|
+
shortEn: "Switch",
|
|
20440
|
+
shortIt: "Interruttore",
|
|
20441
|
+
aliases: []
|
|
20442
|
+
},
|
|
20443
|
+
{
|
|
20444
|
+
id: "sensor",
|
|
20445
|
+
key: "uiLibrary.deviceMeta.noun.type.sensor",
|
|
20446
|
+
en: "Sensor",
|
|
20447
|
+
it: "Sensore",
|
|
20448
|
+
shortEn: "Sensor",
|
|
20449
|
+
shortIt: "Sensore",
|
|
20450
|
+
aliases: []
|
|
20451
|
+
},
|
|
20452
|
+
{
|
|
20453
|
+
id: "thermostat",
|
|
20454
|
+
key: "uiLibrary.deviceMeta.noun.type.thermostat",
|
|
20455
|
+
en: "Thermostat",
|
|
20456
|
+
it: "Termostato",
|
|
20457
|
+
shortEn: "Thermostat",
|
|
20458
|
+
shortIt: "Termostato",
|
|
20459
|
+
aliases: []
|
|
20460
|
+
},
|
|
20461
|
+
{
|
|
20462
|
+
id: "climate",
|
|
20463
|
+
key: "uiLibrary.deviceMeta.noun.type.climate",
|
|
20464
|
+
en: "Air conditioner",
|
|
20465
|
+
it: "Condizionatore",
|
|
20466
|
+
shortEn: "Climate",
|
|
20467
|
+
shortIt: "Condizionatore",
|
|
20468
|
+
aliases: []
|
|
20469
|
+
},
|
|
20470
|
+
{
|
|
20471
|
+
id: "button",
|
|
20472
|
+
key: "uiLibrary.deviceMeta.noun.type.button",
|
|
20473
|
+
en: "Button",
|
|
20474
|
+
it: "Pulsante",
|
|
20475
|
+
shortEn: "Button",
|
|
20476
|
+
shortIt: "Pulsante",
|
|
20477
|
+
aliases: []
|
|
20478
|
+
},
|
|
20479
|
+
{
|
|
20480
|
+
id: "event-emitter",
|
|
20481
|
+
key: "uiLibrary.deviceMeta.noun.type.eventEmitter",
|
|
20482
|
+
en: "Event Emitter",
|
|
20483
|
+
it: "Emettitore di eventi",
|
|
20484
|
+
shortEn: "Event",
|
|
20485
|
+
shortIt: "Evento",
|
|
20486
|
+
aliases: []
|
|
20487
|
+
},
|
|
20488
|
+
{
|
|
20489
|
+
id: "update",
|
|
20490
|
+
key: "uiLibrary.deviceMeta.noun.type.update",
|
|
20491
|
+
en: "Update",
|
|
20492
|
+
it: "Aggiornamento",
|
|
20493
|
+
shortEn: "Update",
|
|
20494
|
+
shortIt: "Aggiornamento",
|
|
20495
|
+
aliases: []
|
|
20496
|
+
},
|
|
20497
|
+
{
|
|
20498
|
+
id: "generic",
|
|
20499
|
+
key: "uiLibrary.deviceMeta.noun.type.generic",
|
|
20500
|
+
en: "Generic",
|
|
20501
|
+
it: "Generico",
|
|
20502
|
+
shortEn: "Generic",
|
|
20503
|
+
shortIt: "Generico",
|
|
20504
|
+
aliases: []
|
|
20505
|
+
},
|
|
20506
|
+
{
|
|
20507
|
+
id: "notifier",
|
|
20508
|
+
key: "uiLibrary.deviceMeta.noun.type.notifier",
|
|
20509
|
+
en: "Notifier",
|
|
20510
|
+
it: "Notificatore",
|
|
20511
|
+
shortEn: "Notifier",
|
|
20512
|
+
shortIt: "Notificatore",
|
|
20513
|
+
aliases: []
|
|
20514
|
+
},
|
|
20515
|
+
{
|
|
20516
|
+
id: "script",
|
|
20517
|
+
key: "uiLibrary.deviceMeta.noun.type.script",
|
|
20518
|
+
en: "Script",
|
|
20519
|
+
it: "Script",
|
|
20520
|
+
shortEn: "Script",
|
|
20521
|
+
shortIt: "Script",
|
|
20522
|
+
aliases: []
|
|
20523
|
+
},
|
|
20524
|
+
{
|
|
20525
|
+
id: "automation",
|
|
20526
|
+
key: "uiLibrary.deviceMeta.noun.type.automation",
|
|
20527
|
+
en: "Automation",
|
|
20528
|
+
it: "Automazione",
|
|
20529
|
+
shortEn: "Automation",
|
|
20530
|
+
shortIt: "Automazione",
|
|
20531
|
+
aliases: []
|
|
20532
|
+
},
|
|
20533
|
+
{
|
|
20534
|
+
id: "lock",
|
|
20535
|
+
key: "uiLibrary.deviceMeta.noun.type.lock",
|
|
20536
|
+
en: "Lock",
|
|
20537
|
+
it: "Serratura",
|
|
20538
|
+
shortEn: "Lock",
|
|
20539
|
+
shortIt: "Serratura",
|
|
20540
|
+
aliases: []
|
|
20541
|
+
},
|
|
20542
|
+
{
|
|
20543
|
+
id: "cover",
|
|
20544
|
+
key: "uiLibrary.deviceMeta.noun.type.cover",
|
|
20545
|
+
en: "Cover",
|
|
20546
|
+
it: "Copertura",
|
|
20547
|
+
shortEn: "Cover",
|
|
20548
|
+
shortIt: "Copertura",
|
|
20549
|
+
aliases: []
|
|
20550
|
+
},
|
|
20551
|
+
{
|
|
20552
|
+
id: "valve",
|
|
20553
|
+
key: "uiLibrary.deviceMeta.noun.type.valve",
|
|
20554
|
+
en: "Valve",
|
|
20555
|
+
it: "Valvola",
|
|
20556
|
+
shortEn: "Valve",
|
|
20557
|
+
shortIt: "Valvola",
|
|
20558
|
+
aliases: []
|
|
20559
|
+
},
|
|
20560
|
+
{
|
|
20561
|
+
id: "humidifier",
|
|
20562
|
+
key: "uiLibrary.deviceMeta.noun.type.humidifier",
|
|
20563
|
+
en: "Humidifier",
|
|
20564
|
+
it: "Umidificatore",
|
|
20565
|
+
shortEn: "Humidifier",
|
|
20566
|
+
shortIt: "Umidificatore",
|
|
20567
|
+
aliases: []
|
|
20568
|
+
},
|
|
20569
|
+
{
|
|
20570
|
+
id: "water-heater",
|
|
20571
|
+
key: "uiLibrary.deviceMeta.noun.type.waterHeater",
|
|
20572
|
+
en: "Water heater",
|
|
20573
|
+
it: "Scaldabagno",
|
|
20574
|
+
shortEn: "Heater",
|
|
20575
|
+
shortIt: "Scaldabagno",
|
|
20576
|
+
aliases: []
|
|
20577
|
+
},
|
|
20578
|
+
{
|
|
20579
|
+
id: "fan",
|
|
20580
|
+
key: "uiLibrary.deviceMeta.noun.type.fan",
|
|
20581
|
+
en: "Fan",
|
|
20582
|
+
it: "Ventilatore",
|
|
20583
|
+
shortEn: "Fan",
|
|
20584
|
+
shortIt: "Ventilatore",
|
|
20585
|
+
aliases: []
|
|
20586
|
+
},
|
|
20587
|
+
{
|
|
20588
|
+
id: "media-player",
|
|
20589
|
+
key: "uiLibrary.deviceMeta.noun.type.mediaPlayer",
|
|
20590
|
+
en: "Media player",
|
|
20591
|
+
it: "Lettore multimediale",
|
|
20592
|
+
shortEn: "Player",
|
|
20593
|
+
shortIt: "Lettore",
|
|
20594
|
+
aliases: []
|
|
20595
|
+
},
|
|
20596
|
+
{
|
|
20597
|
+
id: "alarm-panel",
|
|
20598
|
+
key: "uiLibrary.deviceMeta.noun.type.alarmPanel",
|
|
20599
|
+
en: "Alarm panel",
|
|
20600
|
+
it: "Pannello allarme",
|
|
20601
|
+
shortEn: "Alarm",
|
|
20602
|
+
shortIt: "Allarme",
|
|
20603
|
+
aliases: []
|
|
20604
|
+
},
|
|
20605
|
+
{
|
|
20606
|
+
id: "control",
|
|
20607
|
+
key: "uiLibrary.deviceMeta.noun.type.control",
|
|
20608
|
+
en: "Control",
|
|
20609
|
+
it: "Controllo",
|
|
20610
|
+
shortEn: "Control",
|
|
20611
|
+
shortIt: "Controllo",
|
|
20612
|
+
aliases: []
|
|
20613
|
+
},
|
|
20614
|
+
{
|
|
20615
|
+
id: "presence",
|
|
20616
|
+
key: "uiLibrary.deviceMeta.noun.type.presence",
|
|
20617
|
+
en: "Presence",
|
|
20618
|
+
it: "Presenza",
|
|
20619
|
+
shortEn: "Presence",
|
|
20620
|
+
shortIt: "Presenza",
|
|
20621
|
+
aliases: []
|
|
20622
|
+
},
|
|
20623
|
+
{
|
|
20624
|
+
id: "weather",
|
|
20625
|
+
key: "uiLibrary.deviceMeta.noun.type.weather",
|
|
20626
|
+
en: "Weather",
|
|
20627
|
+
it: "Meteo",
|
|
20628
|
+
shortEn: "Weather",
|
|
20629
|
+
shortIt: "Meteo",
|
|
20630
|
+
aliases: []
|
|
20631
|
+
},
|
|
20632
|
+
{
|
|
20633
|
+
id: "vacuum",
|
|
20634
|
+
key: "uiLibrary.deviceMeta.noun.type.vacuum",
|
|
20635
|
+
en: "Vacuum",
|
|
20636
|
+
it: "Aspirapolvere",
|
|
20637
|
+
shortEn: "Vacuum",
|
|
20638
|
+
shortIt: "Aspirapolvere",
|
|
20639
|
+
aliases: []
|
|
20640
|
+
},
|
|
20641
|
+
{
|
|
20642
|
+
id: "lawn-mower",
|
|
20643
|
+
key: "uiLibrary.deviceMeta.noun.type.lawnMower",
|
|
20644
|
+
en: "Lawn mower",
|
|
20645
|
+
it: "Tagliaerba",
|
|
20646
|
+
shortEn: "Mower",
|
|
20647
|
+
shortIt: "Tagliaerba",
|
|
20648
|
+
aliases: []
|
|
20649
|
+
},
|
|
20650
|
+
{
|
|
20651
|
+
id: "container",
|
|
20652
|
+
key: "uiLibrary.deviceMeta.noun.type.container",
|
|
20653
|
+
en: "Container",
|
|
20654
|
+
it: "Contenitore",
|
|
20655
|
+
shortEn: "Container",
|
|
20656
|
+
shortIt: "Contenitore",
|
|
20657
|
+
aliases: []
|
|
20658
|
+
},
|
|
20659
|
+
{
|
|
20660
|
+
id: "image",
|
|
20661
|
+
key: "uiLibrary.deviceMeta.noun.type.image",
|
|
20662
|
+
en: "Image",
|
|
20663
|
+
it: "Immagine",
|
|
20664
|
+
shortEn: "Image",
|
|
20665
|
+
shortIt: "Immagine",
|
|
20666
|
+
aliases: []
|
|
20667
|
+
},
|
|
20668
|
+
{
|
|
20669
|
+
id: "pet-feeder",
|
|
20670
|
+
key: "uiLibrary.deviceMeta.noun.type.petFeeder",
|
|
20671
|
+
en: "Pet feeder",
|
|
20672
|
+
it: "Distributore di cibo per animali",
|
|
20673
|
+
shortEn: "Feeder",
|
|
20674
|
+
shortIt: "Distributore",
|
|
20675
|
+
aliases: []
|
|
20676
|
+
},
|
|
20677
|
+
{
|
|
20678
|
+
id: "dishwasher",
|
|
20679
|
+
key: "uiLibrary.deviceMeta.noun.type.dishwasher",
|
|
20680
|
+
en: "Dishwasher",
|
|
20681
|
+
it: "Lavastoviglie",
|
|
20682
|
+
shortEn: "Dishwasher",
|
|
20683
|
+
shortIt: "Lavastoviglie",
|
|
20684
|
+
aliases: []
|
|
20685
|
+
}
|
|
20686
|
+
];
|
|
20687
|
+
var FALLBACK_NOUN = {
|
|
20688
|
+
id: "",
|
|
20689
|
+
key: "uiLibrary.deviceMeta.noun.fallback",
|
|
20690
|
+
en: "Device",
|
|
20691
|
+
it: "Dispositivo",
|
|
20692
|
+
shortEn: "Device",
|
|
20693
|
+
shortIt: "Dispositivo",
|
|
20694
|
+
aliases: []
|
|
20695
|
+
};
|
|
20696
|
+
function findNoun(list, id) {
|
|
20697
|
+
if (id === null || id.length === 0) return void 0;
|
|
20698
|
+
return list.find((spec) => spec.id === id);
|
|
20699
|
+
}
|
|
20700
|
+
/** Role wins when it has a noun; otherwise the type. Unknown types fall back. */
|
|
20701
|
+
function nounSpecFor(role, type) {
|
|
20702
|
+
if (role !== null) {
|
|
20703
|
+
const byRole = findNoun(DEVICE_ROLE_NOUNS, role);
|
|
20704
|
+
if (byRole !== void 0) return byRole;
|
|
20705
|
+
}
|
|
20706
|
+
return findNoun(DEVICE_TYPE_NOUNS, type) ?? FALLBACK_NOUN;
|
|
20707
|
+
}
|
|
20708
|
+
function stockPhrases(role, type) {
|
|
20709
|
+
const phrases = [];
|
|
20710
|
+
const specs = [findNoun(DEVICE_ROLE_NOUNS, role), findNoun(DEVICE_TYPE_NOUNS, type)];
|
|
20711
|
+
for (const spec of specs) {
|
|
20712
|
+
if (spec === void 0) continue;
|
|
20713
|
+
phrases.push(spec.en, spec.it, spec.shortEn, spec.shortIt, ...spec.aliases);
|
|
20714
|
+
}
|
|
20715
|
+
return phrases;
|
|
20716
|
+
}
|
|
20717
|
+
function isDeviceNameStock(text, role, type) {
|
|
20718
|
+
const folded = foldDeviceName(text);
|
|
20719
|
+
if (folded.length === 0) return true;
|
|
20720
|
+
return stockPhrases(role, type).some((phrase) => foldDeviceName(phrase) === folded);
|
|
20721
|
+
}
|
|
20722
|
+
/** Noun table for a locale. Tests and the viewer parity spec use this directly. */
|
|
20723
|
+
function deviceNameNouns(locale) {
|
|
20724
|
+
return {
|
|
20725
|
+
shortNoun(role, type) {
|
|
20726
|
+
const spec = nounSpecFor(role, type);
|
|
20727
|
+
return locale === "it" ? spec.shortIt : spec.shortEn;
|
|
20728
|
+
},
|
|
20729
|
+
isStockPhrase(text, role, type) {
|
|
20730
|
+
return isDeviceNameStock(text, role, type);
|
|
20731
|
+
}
|
|
20732
|
+
};
|
|
20733
|
+
}
|
|
20734
|
+
//#endregion
|
|
20735
|
+
//#region src/composites/device-name/use-device-label.ts
|
|
20736
|
+
/**
|
|
20737
|
+
* `useDeviceLabel` is the string `DeviceName` renders — sort keys, aria
|
|
20738
|
+
* labels, confirm copy and search titles call it instead of painting
|
|
20739
|
+
* `device.name`.
|
|
20740
|
+
*/
|
|
20741
|
+
function useDeviceNameNouns() {
|
|
20742
|
+
const t = useUiText();
|
|
20743
|
+
return {
|
|
20744
|
+
shortNoun(role, type) {
|
|
20745
|
+
const spec = nounSpecFor(role, type);
|
|
20746
|
+
return t(spec.key, spec.shortEn);
|
|
20747
|
+
},
|
|
20748
|
+
isStockPhrase(text, role, type) {
|
|
20749
|
+
return isDeviceNameStock(text, role, type);
|
|
20750
|
+
}
|
|
20751
|
+
};
|
|
20752
|
+
}
|
|
20753
|
+
function placeholderParent(id) {
|
|
20754
|
+
return {
|
|
20755
|
+
id,
|
|
20756
|
+
name: `#${String(id)}`,
|
|
20757
|
+
type: "unknown",
|
|
20758
|
+
stableId: "",
|
|
20759
|
+
role: null,
|
|
20760
|
+
parentDeviceId: null
|
|
20761
|
+
};
|
|
20762
|
+
}
|
|
20763
|
+
function parentFromIndex(device, index) {
|
|
20764
|
+
const parentId = device.parentDeviceId;
|
|
20765
|
+
if (parentId === null || parentId === void 0) return null;
|
|
20766
|
+
return index.byId.get(parentId) ?? placeholderParent(parentId);
|
|
20767
|
+
}
|
|
20768
|
+
function siblingsFromIndex(device, index) {
|
|
20769
|
+
const parentId = device.parentDeviceId;
|
|
20770
|
+
if (parentId === null || parentId === void 0) return [];
|
|
20771
|
+
const ids = index.childIds.get(parentId) ?? [];
|
|
20772
|
+
const siblings = [];
|
|
20773
|
+
for (const id of ids) {
|
|
20774
|
+
const row = index.byId.get(id);
|
|
20775
|
+
if (row !== void 0) siblings.push(row);
|
|
20776
|
+
}
|
|
20777
|
+
if (!siblings.some((sibling) => sibling.id === device.id)) siblings.push(device);
|
|
20778
|
+
return siblings;
|
|
20779
|
+
}
|
|
20780
|
+
/**
|
|
20781
|
+
* Label for a device the caller already holds. While the fleet has not
|
|
20782
|
+
* answered and no parent was passed, this is the stored name — not `#id`.
|
|
20783
|
+
*/
|
|
20784
|
+
function resolveDeviceLabel(device, form, index, nouns, scope) {
|
|
20785
|
+
const subject = index?.byId.get(device.id) ?? device;
|
|
20786
|
+
const parentId = subject.parentDeviceId;
|
|
20787
|
+
if (parentId !== null && parentId !== void 0 && index === null && scope?.parent === void 0) return subject.name;
|
|
20788
|
+
return formatDeviceName(subject, form, {
|
|
20789
|
+
parent: scope?.parent !== void 0 ? scope.parent : index === null ? null : parentFromIndex(subject, index),
|
|
20790
|
+
siblings: scope?.siblings ?? (index === null ? [] : siblingsFromIndex(subject, index))
|
|
20791
|
+
}, nouns);
|
|
20792
|
+
}
|
|
20793
|
+
function useDeviceLabel(device, form, scope) {
|
|
20794
|
+
return resolveDeviceLabel(device, form, useDeviceNameIndex(), useDeviceNameNouns(), scope);
|
|
20795
|
+
}
|
|
20796
|
+
/** `#id` until the fleet answers, and `#id` when the id is not in it. */
|
|
20797
|
+
function useDeviceLabelById(id, form, pendingName) {
|
|
20798
|
+
const index = useDeviceNameIndex();
|
|
20799
|
+
const nouns = useDeviceNameNouns();
|
|
20800
|
+
if (index === null) return pendingName ?? `#${String(id)}`;
|
|
20801
|
+
const device = index.byId.get(id);
|
|
20802
|
+
if (device === void 0) return `#${String(id)}`;
|
|
20803
|
+
return resolveDeviceLabel(device, form, index, nouns);
|
|
20804
|
+
}
|
|
20805
|
+
//#endregion
|
|
20806
|
+
//#region src/composites/device-name/DeviceName.tsx
|
|
20807
|
+
function DeviceName({ device, form, parent, siblings, className, testId }) {
|
|
20808
|
+
const label = useDeviceLabel(device, form, {
|
|
20809
|
+
...parent !== void 0 ? { parent } : {},
|
|
20810
|
+
...siblings !== void 0 ? { siblings } : {}
|
|
20811
|
+
});
|
|
20812
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
20813
|
+
className,
|
|
20814
|
+
title: label,
|
|
20815
|
+
"data-testid": testId,
|
|
20816
|
+
children: label
|
|
20817
|
+
});
|
|
20818
|
+
}
|
|
20819
|
+
//#endregion
|
|
19627
20820
|
//#region src/hooks/use-device-proxy.ts
|
|
19628
20821
|
/**
|
|
19629
20822
|
* useDeviceProxy — canonical React entry point for a device.
|
|
@@ -20526,6 +21719,9 @@ function GridCellBox({ cell, selected, onSelect, onDragStart }) {
|
|
|
20526
21719
|
}, handle))
|
|
20527
21720
|
});
|
|
20528
21721
|
}
|
|
21722
|
+
function CameraOptionLabel({ camera }) {
|
|
21723
|
+
return useDeviceLabel(camera, "compact");
|
|
21724
|
+
}
|
|
20529
21725
|
function CellInspector({ cell, index, cameras, onChange, onRemove }) {
|
|
20530
21726
|
const t = useUiText();
|
|
20531
21727
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -20556,7 +21752,7 @@ function CellInspector({ cell, index, cameras, onChange, onRemove }) {
|
|
|
20556
21752
|
className: "flex-1 rounded border border-border bg-transparent px-1 py-0.5",
|
|
20557
21753
|
children: cameras.map((camera) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
20558
21754
|
value: String(camera.id),
|
|
20559
|
-
children: camera
|
|
21755
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CameraOptionLabel, { camera })
|
|
20560
21756
|
}, camera.id))
|
|
20561
21757
|
})]
|
|
20562
21758
|
}),
|
|
@@ -31013,13 +32209,13 @@ function InfoBox({ field }) {
|
|
|
31013
32209
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
31014
32210
|
className: `rounded-md border-l-4 px-3 py-2.5 ${styles.border} ${styles.bg}`,
|
|
31015
32211
|
children: [field.label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
31016
|
-
className: `text-xs font-semibold mb-0.5 ${styles.text}
|
|
32212
|
+
className: field.content.length > 0 ? `text-xs font-semibold mb-0.5 ${styles.text}` : "text-xs text-foreground-subtle leading-relaxed whitespace-pre-line break-words",
|
|
31017
32213
|
children: field.label
|
|
31018
32214
|
}), isHtml ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
31019
32215
|
className: "text-xs text-foreground-subtle leading-relaxed info-html-content",
|
|
31020
32216
|
dangerouslySetInnerHTML: { __html: sanitizeInfoHtml(field.content) }
|
|
31021
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
31022
|
-
className: "text-xs text-foreground-subtle leading-relaxed whitespace-pre-line",
|
|
32217
|
+
}) : field.content.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
32218
|
+
className: "text-xs text-foreground-subtle leading-relaxed whitespace-pre-line break-words",
|
|
31023
32219
|
children: field.content
|
|
31024
32220
|
})]
|
|
31025
32221
|
})
|
|
@@ -48244,17 +49440,19 @@ function SensorHeroInner({ trpc, device }) {
|
|
|
48244
49440
|
if (resolution.kind === "quiet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
48245
49441
|
className: "flex flex-col items-center justify-center gap-2 rounded-lg border border-border bg-surface p-4 min-h-[96px]",
|
|
48246
49442
|
"data-testid": "sensor-hero-quiet",
|
|
48247
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48248
|
-
|
|
48249
|
-
|
|
49443
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49444
|
+
device,
|
|
49445
|
+
form: "full",
|
|
49446
|
+
className: "text-sm text-foreground-subtle"
|
|
48250
49447
|
})
|
|
48251
49448
|
});
|
|
48252
49449
|
const slice = resolution.kind === "value" ? resolution.slice : void 0;
|
|
48253
49450
|
if (descriptor === void 0 || slice === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
48254
49451
|
className: "flex flex-col items-center justify-center gap-2 rounded-lg border border-border bg-surface p-4 min-h-[96px]",
|
|
48255
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48256
|
-
|
|
48257
|
-
|
|
49452
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49453
|
+
device,
|
|
49454
|
+
form: "full",
|
|
49455
|
+
className: "text-sm text-foreground-subtle"
|
|
48258
49456
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
48259
49457
|
className: "text-xs text-foreground-subtle italic",
|
|
48260
49458
|
children: t("uiLibrary.sensorHeroCard.awaiting", "Awaiting state…")
|
|
@@ -48294,9 +49492,10 @@ function SensorHeroInner({ trpc, device }) {
|
|
|
48294
49492
|
"data-testid": "sensor-hero-occupancy",
|
|
48295
49493
|
children: occupancyOn ? t("uiLibrary.sensorHeroCard.occupied", "Occupied") : t("uiLibrary.sensorHeroCard.clear", "Clear")
|
|
48296
49494
|
}),
|
|
48297
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48298
|
-
|
|
48299
|
-
|
|
49495
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49496
|
+
device,
|
|
49497
|
+
form: "full",
|
|
49498
|
+
className: "text-sm text-foreground-subtle"
|
|
48300
49499
|
})
|
|
48301
49500
|
]
|
|
48302
49501
|
});
|
|
@@ -48311,9 +49510,10 @@ function SensorHeroInner({ trpc, device }) {
|
|
|
48311
49510
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
48312
49511
|
className: cn("inline-flex items-center rounded px-3 py-1.5 text-lg font-semibold", active ? "bg-warning/15 text-warning" : "bg-surface-subtle text-foreground-subtle"),
|
|
48313
49512
|
children: label
|
|
48314
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48315
|
-
|
|
48316
|
-
|
|
49513
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49514
|
+
device,
|
|
49515
|
+
form: "full",
|
|
49516
|
+
className: "text-sm text-foreground-subtle"
|
|
48317
49517
|
})]
|
|
48318
49518
|
});
|
|
48319
49519
|
}
|
|
@@ -48321,9 +49521,10 @@ function SensorHeroInner({ trpc, device }) {
|
|
|
48321
49521
|
if (!isStringSliceValue(slice)) return null;
|
|
48322
49522
|
if (slice.value === "") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
48323
49523
|
className: "flex flex-col items-center justify-center gap-2 rounded-lg border border-border bg-surface p-4 min-h-[96px]",
|
|
48324
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48325
|
-
|
|
48326
|
-
|
|
49524
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49525
|
+
device,
|
|
49526
|
+
form: "full",
|
|
49527
|
+
className: "text-sm text-foreground-subtle"
|
|
48327
49528
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
48328
49529
|
className: "text-xs text-foreground-subtle italic",
|
|
48329
49530
|
children: t("uiLibrary.sensorHeroCard.awaiting", "Awaiting state…")
|
|
@@ -48335,9 +49536,10 @@ function SensorHeroInner({ trpc, device }) {
|
|
|
48335
49536
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
48336
49537
|
className: "text-3xl font-semibold tabular-nums text-foreground",
|
|
48337
49538
|
children: formatControlDateTime(slice.value, format)
|
|
48338
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48339
|
-
|
|
48340
|
-
|
|
49539
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49540
|
+
device,
|
|
49541
|
+
form: "full",
|
|
49542
|
+
className: "text-sm text-foreground-subtle"
|
|
48341
49543
|
})]
|
|
48342
49544
|
});
|
|
48343
49545
|
}
|
|
@@ -48349,9 +49551,10 @@ function SensorHeroInner({ trpc, device }) {
|
|
|
48349
49551
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
48350
49552
|
className: "text-xl font-semibold text-foreground",
|
|
48351
49553
|
children: slice.value
|
|
48352
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48353
|
-
|
|
48354
|
-
|
|
49554
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49555
|
+
device,
|
|
49556
|
+
form: "full",
|
|
49557
|
+
className: "text-sm text-foreground-subtle"
|
|
48355
49558
|
})]
|
|
48356
49559
|
});
|
|
48357
49560
|
}
|
|
@@ -48362,9 +49565,10 @@ function SensorHeroInner({ trpc, device }) {
|
|
|
48362
49565
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
48363
49566
|
className: cn("inline-flex items-center rounded px-3 py-1.5 text-lg font-semibold", slice.state === "home" ? "bg-success/15 text-success" : "bg-surface-subtle text-foreground-subtle"),
|
|
48364
49567
|
children: label
|
|
48365
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
48366
|
-
|
|
48367
|
-
|
|
49568
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
49569
|
+
device,
|
|
49570
|
+
form: "full",
|
|
49571
|
+
className: "text-sm text-foreground-subtle"
|
|
48368
49572
|
})]
|
|
48369
49573
|
});
|
|
48370
49574
|
}
|
|
@@ -55119,7 +56323,9 @@ var CONTROL_FILLS = {
|
|
|
55119
56323
|
[_camstack_types.DeviceType.Container]: false,
|
|
55120
56324
|
[_camstack_types.DeviceType.Image]: false,
|
|
55121
56325
|
[_camstack_types.DeviceType.PetFeeder]: false,
|
|
55122
|
-
[_camstack_types.DeviceType.Dishwasher]: false
|
|
56326
|
+
[_camstack_types.DeviceType.Dishwasher]: false,
|
|
56327
|
+
[_camstack_types.DeviceType.Washer]: false,
|
|
56328
|
+
[_camstack_types.DeviceType.Dryer]: false
|
|
55123
56329
|
};
|
|
55124
56330
|
var DEVICE_TYPE_VALUES = new Set(Object.values(_camstack_types.DeviceType));
|
|
55125
56331
|
/**
|
|
@@ -56375,6 +57581,7 @@ function useContainerChildren(deviceId) {
|
|
|
56375
57581
|
var SENSOR_VALUE_TYPES = new Set([_camstack_types.DeviceType.Sensor, _camstack_types.DeviceType.Presence]);
|
|
56376
57582
|
function DeviceItemActions({ trpc, device, controlPlacement }) {
|
|
56377
57583
|
const containerChildren = useContainerChildren(device.id);
|
|
57584
|
+
const deviceLabel = useDeviceLabel(device, "compact");
|
|
56378
57585
|
const placement = controlPlacement ?? "right";
|
|
56379
57586
|
if (!!device.disabled) return null;
|
|
56380
57587
|
if (device.type === _camstack_types.DeviceType.Container) {
|
|
@@ -56430,7 +57637,7 @@ function DeviceItemActions({ trpc, device, controlPlacement }) {
|
|
|
56430
57637
|
showReboot && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RebootQuickAction, {
|
|
56431
57638
|
trpc,
|
|
56432
57639
|
deviceId: device.id,
|
|
56433
|
-
deviceName:
|
|
57640
|
+
deviceName: deviceLabel
|
|
56434
57641
|
}),
|
|
56435
57642
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdminLinkQuickAction, {
|
|
56436
57643
|
trpc,
|
|
@@ -56666,9 +57873,16 @@ function ChildRow$1({ trpc, child, onNavigate, parentName }) {
|
|
|
56666
57873
|
running: runningSlice === void 0 || runningSlice.running === null ? null : runningSlice.running,
|
|
56667
57874
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChildIcon, { className: "h-3 w-3 text-foreground-subtle flex-shrink-0" })
|
|
56668
57875
|
}),
|
|
56669
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
56670
|
-
|
|
56671
|
-
|
|
57876
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
57877
|
+
device: child,
|
|
57878
|
+
form: "nested",
|
|
57879
|
+
parent: {
|
|
57880
|
+
id: child.parentDeviceId ?? 0,
|
|
57881
|
+
name: parentName,
|
|
57882
|
+
type: "unknown",
|
|
57883
|
+
stableId: ""
|
|
57884
|
+
},
|
|
57885
|
+
className: "text-[10.5px] text-foreground flex-1 truncate"
|
|
56672
57886
|
}),
|
|
56673
57887
|
showMotionTrigger && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChildMotionTriggerToggle, {
|
|
56674
57888
|
trpc,
|
|
@@ -56775,8 +57989,9 @@ function IconAction({ icon: Icon, label, onClick, danger = false }) {
|
|
|
56775
57989
|
function DeviceDeleteAction({ device, onDelete }) {
|
|
56776
57990
|
const t = useUiText();
|
|
56777
57991
|
const confirm = useConfirm();
|
|
57992
|
+
const deviceLabel = useDeviceLabel(device, "full");
|
|
56778
57993
|
const requestDelete = async () => {
|
|
56779
|
-
const label =
|
|
57994
|
+
const label = deviceLabel.trim() !== "" ? deviceLabel : `#${String(device.id)}`;
|
|
56780
57995
|
if (await confirm({
|
|
56781
57996
|
title: t("uiLibrary.deviceDeleteAction.title", "Delete device?"),
|
|
56782
57997
|
message: t("uiLibrary.deviceDeleteAction.message", "This will remove \"{{label}}\" and all its settings. This action cannot be undone.", { label }),
|
|
@@ -57059,7 +58274,7 @@ var CHEVRON_SLOT_CLASS = {
|
|
|
57059
58274
|
horizontal: "h-3.5 w-3.5",
|
|
57060
58275
|
stacked: "h-4 w-4 mt-0.5"
|
|
57061
58276
|
};
|
|
57062
|
-
function DeviceItemHeader({ trpc, device, variant, flags, parent, integrationIcon, hasChildren, expanded, onToggleExpand, onNavigateToParent, stacked = false, nameOverflow = "truncate" }) {
|
|
58277
|
+
function DeviceItemHeader({ trpc, device, variant, flags, parent, integrationIcon, hasChildren, expanded, onToggleExpand, onNavigateToParent, stacked = false, nameOverflow = "truncate", nameForm = "compact" }) {
|
|
57063
58278
|
const t = useUiText();
|
|
57064
58279
|
const containerChildren = useContainerChildren(device.id);
|
|
57065
58280
|
const roleDefaults = useRoleDisplayDefaults();
|
|
@@ -57070,6 +58285,13 @@ function DeviceItemHeader({ trpc, device, variant, flags, parent, integrationIco
|
|
|
57070
58285
|
const slotClass = stacked ? CHEVRON_SLOT_CLASS.stacked : CHEVRON_SLOT_CLASS.horizontal;
|
|
57071
58286
|
const iconClass = cn("text-foreground-subtle flex-shrink-0", stacked ? "h-4 w-4 mt-0.5" : variant === "minimal" ? "h-3 w-3" : "h-3.5 w-3.5");
|
|
57072
58287
|
const lineClass = nameOverflow === "scroll" ? NAME_TEXT_CLASS : "truncate";
|
|
58288
|
+
const nameParent = nameForm === "nested" && parent !== null ? {
|
|
58289
|
+
id: parent.id,
|
|
58290
|
+
name: parent.name,
|
|
58291
|
+
type: parent.type ?? "unknown",
|
|
58292
|
+
stableId: ""
|
|
58293
|
+
} : void 0;
|
|
58294
|
+
const parentLabel = useDeviceLabelById(parent?.id ?? 0, "compact", parent?.name);
|
|
57073
58295
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
57074
58296
|
className: cn(stacked ? "flex items-start gap-2 w-full min-w-0" : "flex items-center gap-2 flex-1 min-w-0"),
|
|
57075
58297
|
children: [
|
|
@@ -57100,11 +58322,12 @@ function DeviceItemHeader({ trpc, device, variant, flags, parent, integrationIco
|
|
|
57100
58322
|
children: [flags.showIntegrationIcon && integrationIcon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57101
58323
|
className: "flex-shrink-0",
|
|
57102
58324
|
children: integrationIcon
|
|
57103
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
57104
|
-
|
|
57105
|
-
|
|
57106
|
-
|
|
57107
|
-
|
|
58325
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
58326
|
+
device,
|
|
58327
|
+
form: nameForm,
|
|
58328
|
+
...nameParent !== void 0 ? { parent: nameParent } : {},
|
|
58329
|
+
testId: "device-name",
|
|
58330
|
+
className: cn("font-semibold text-foreground", stacked ? "text-[13px] leading-snug line-clamp-2 break-words" : cn(lineClass, variant === "minimal" ? "text-[10.5px]" : "text-[11px]"))
|
|
57108
58331
|
})]
|
|
57109
58332
|
}),
|
|
57110
58333
|
(flags.showId || flags.showStableId) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -57133,12 +58356,12 @@ function DeviceItemHeader({ trpc, device, variant, flags, parent, integrationIco
|
|
|
57133
58356
|
},
|
|
57134
58357
|
className: cn("mt-0.5 inline-flex items-center gap-1 text-[9px] text-foreground-subtle hover:text-primary transition-colors", nameOverflow === "scroll" ? "md:max-w-full" : "max-w-full"),
|
|
57135
58358
|
title: t("uiLibrary.deviceItemHeader.openParent", "Open parent: {{name}} (#{{id}})", {
|
|
57136
|
-
name:
|
|
58359
|
+
name: parentLabel,
|
|
57137
58360
|
id: parent.id
|
|
57138
58361
|
}),
|
|
57139
58362
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Network, { className: "h-2.5 w-2.5 shrink-0" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
57140
58363
|
className: lineClass,
|
|
57141
|
-
children: t("uiLibrary.deviceItemHeader.under", "Under: {{name}}", { name:
|
|
58364
|
+
children: t("uiLibrary.deviceItemHeader.under", "Under: {{name}}", { name: parentLabel })
|
|
57142
58365
|
})]
|
|
57143
58366
|
})
|
|
57144
58367
|
]
|
|
@@ -57267,7 +58490,9 @@ function HoverZoomImage({ src, alt, caption, placeholder = "No image", thumbClas
|
|
|
57267
58490
|
* the 288 px hover zoom. */
|
|
57268
58491
|
var PREVIEW_SNAPSHOT_WIDTH = 480;
|
|
57269
58492
|
function DeviceItemPreview({ trpc, device, status, enabled, showStatusPills = false }) {
|
|
57270
|
-
const
|
|
58493
|
+
const liveActive = enabled && device.online;
|
|
58494
|
+
const deviceLabel = useDeviceLabel(device, "compact");
|
|
58495
|
+
const snapshot = useDeviceSnapshotImage(liveActive ? device.id : null, { width: PREVIEW_SNAPSHOT_WIDTH });
|
|
57271
58496
|
const isBatteryOperated = (device.features ?? []).includes("battery-operated");
|
|
57272
58497
|
const wantPills = showStatusPills && isBatteryOperated && !device.disabled;
|
|
57273
58498
|
const batteryStatus = useDeviceBattery(trpc, wantPills ? device.id : null);
|
|
@@ -57283,7 +58508,7 @@ function DeviceItemPreview({ trpc, device, status, enabled, showStatusPills = fa
|
|
|
57283
58508
|
wantLinkPill && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NetworkLinkBadge, { status: linkStatus }),
|
|
57284
58509
|
enabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HoverZoomImage, {
|
|
57285
58510
|
src: offline ? null : snapshot.src,
|
|
57286
|
-
alt:
|
|
58511
|
+
alt: deviceLabel,
|
|
57287
58512
|
placeholder,
|
|
57288
58513
|
thumbClassName: "h-7 w-7 rounded"
|
|
57289
58514
|
})
|
|
@@ -57506,6 +58731,14 @@ function DeviceItem(props) {
|
|
|
57506
58731
|
const flags = resolveFlags(props);
|
|
57507
58732
|
const variant = props.variant ?? "compact";
|
|
57508
58733
|
const view = props.view ?? "card";
|
|
58734
|
+
const nameForm = props.isAccessoryRow ? "nested" : "compact";
|
|
58735
|
+
const nameParent = nameForm === "nested" && parent ? {
|
|
58736
|
+
id: parent.id,
|
|
58737
|
+
name: parent.name,
|
|
58738
|
+
type: parent.type ?? "unknown",
|
|
58739
|
+
stableId: ""
|
|
58740
|
+
} : void 0;
|
|
58741
|
+
const rowLabel = useDeviceLabel(device, nameForm, nameParent !== void 0 ? { parent: nameParent } : void 0);
|
|
57509
58742
|
const enabled = !device.disabled;
|
|
57510
58743
|
const isCamera = device.isCamera ?? device.type.toLowerCase() === "camera";
|
|
57511
58744
|
const childrenList = props.children ?? [];
|
|
@@ -57581,7 +58814,7 @@ function DeviceItem(props) {
|
|
|
57581
58814
|
checked: selection.selected,
|
|
57582
58815
|
onChange: selection.onToggle,
|
|
57583
58816
|
onClick: (e) => e.stopPropagation(),
|
|
57584
|
-
"aria-label": t("uiLibrary.deviceItem.select", "Select {{name}}", { name:
|
|
58817
|
+
"aria-label": t("uiLibrary.deviceItem.select", "Select {{name}}", { name: rowLabel }),
|
|
57585
58818
|
className: "flex-shrink-0"
|
|
57586
58819
|
}),
|
|
57587
58820
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceItemHeader, {
|
|
@@ -57590,6 +58823,7 @@ function DeviceItem(props) {
|
|
|
57590
58823
|
variant,
|
|
57591
58824
|
flags,
|
|
57592
58825
|
parent: parent ?? null,
|
|
58826
|
+
nameForm,
|
|
57593
58827
|
integrationIcon: integrationIcon ?? null,
|
|
57594
58828
|
hasChildren,
|
|
57595
58829
|
expanded,
|
|
@@ -57658,7 +58892,7 @@ function DeviceItem(props) {
|
|
|
57658
58892
|
checked: selection.selected,
|
|
57659
58893
|
onChange: selection.onToggle,
|
|
57660
58894
|
onClick: (e) => e.stopPropagation(),
|
|
57661
|
-
"aria-label": t("uiLibrary.deviceItem.select", "Select {{name}}", { name:
|
|
58895
|
+
"aria-label": t("uiLibrary.deviceItem.select", "Select {{name}}", { name: rowLabel }),
|
|
57662
58896
|
className: "flex-shrink-0 mt-0.5"
|
|
57663
58897
|
}),
|
|
57664
58898
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceItemHeader, {
|
|
@@ -57667,6 +58901,7 @@ function DeviceItem(props) {
|
|
|
57667
58901
|
variant,
|
|
57668
58902
|
flags,
|
|
57669
58903
|
parent: parent ?? null,
|
|
58904
|
+
nameForm,
|
|
57670
58905
|
integrationIcon: integrationIcon ?? null,
|
|
57671
58906
|
hasChildren,
|
|
57672
58907
|
expanded,
|
|
@@ -57727,6 +58962,14 @@ function DeviceItemTableRow(props) {
|
|
|
57727
58962
|
const t = useUiText();
|
|
57728
58963
|
const { trpc, device, variant, flags, parent, integrationIcon, accessoryCount, adoptedCount, hasChildren, expanded, onToggleExpand, onNavigate, onRowClick, rowSelects, rowSelected, displayStatus, isCamera, showSnapshot, isAccessoryRow, indentLevel, className, renderRowAction, onDelete, selection, showTypeCell, showManufacturerCell, showFeaturesCell } = props;
|
|
57729
58964
|
const containerChildren = useContainerChildren(device.id);
|
|
58965
|
+
const nameForm = isAccessoryRow ? "nested" : "compact";
|
|
58966
|
+
const nameParent = nameForm === "nested" && parent ? {
|
|
58967
|
+
id: parent.id,
|
|
58968
|
+
name: parent.name,
|
|
58969
|
+
type: parent.type ?? "unknown",
|
|
58970
|
+
stableId: ""
|
|
58971
|
+
} : void 0;
|
|
58972
|
+
const rowLabel = useDeviceLabel(device, nameForm, nameParent !== void 0 ? { parent: nameParent } : void 0);
|
|
57730
58973
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
|
|
57731
58974
|
onClick: onRowClick,
|
|
57732
58975
|
...rowSelects ? {
|
|
@@ -57751,7 +58994,7 @@ function DeviceItemTableRow(props) {
|
|
|
57751
58994
|
checked: selection.selected,
|
|
57752
58995
|
onChange: selection.onToggle,
|
|
57753
58996
|
onClick: (e) => e.stopPropagation(),
|
|
57754
|
-
"aria-label": t("uiLibrary.deviceItem.select", "Select {{name}}", { name:
|
|
58997
|
+
"aria-label": t("uiLibrary.deviceItem.select", "Select {{name}}", { name: rowLabel }),
|
|
57755
58998
|
className: "flex-shrink-0"
|
|
57756
58999
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceItemHeader, {
|
|
57757
59000
|
trpc,
|
|
@@ -57759,6 +59002,7 @@ function DeviceItemTableRow(props) {
|
|
|
57759
59002
|
variant,
|
|
57760
59003
|
flags,
|
|
57761
59004
|
parent,
|
|
59005
|
+
nameForm,
|
|
57762
59006
|
integrationIcon,
|
|
57763
59007
|
hasChildren,
|
|
57764
59008
|
expanded,
|
|
@@ -58497,13 +59741,13 @@ function TableRowGroup({ parent, accessories, hasAccessories, expanded, onToggle
|
|
|
58497
59741
|
function AccessorySubRow({ trpc, accessory, parentName, showType, showManufacturer, showFeatures, onNavigate, muted }) {
|
|
58498
59742
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceItem, {
|
|
58499
59743
|
trpc,
|
|
58500
|
-
device:
|
|
58501
|
-
...accessory,
|
|
58502
|
-
name: childListName(accessory, parentName)
|
|
58503
|
-
},
|
|
59744
|
+
device: accessory,
|
|
58504
59745
|
view: "table",
|
|
58505
59746
|
integrationIcon: null,
|
|
58506
|
-
parent: null
|
|
59747
|
+
parent: accessory.parentDeviceId === null ? null : {
|
|
59748
|
+
id: accessory.parentDeviceId,
|
|
59749
|
+
name: parentName
|
|
59750
|
+
},
|
|
58507
59751
|
isAccessoryRow: true,
|
|
58508
59752
|
showChildrenAccordion: false,
|
|
58509
59753
|
onNavigate: onNavigate ?? void 0,
|
|
@@ -59302,6 +60546,15 @@ function DeviceExportSetup({ addonId }) {
|
|
|
59302
60546
|
}), status.setup && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupSection, { setup: status.setup })]
|
|
59303
60547
|
});
|
|
59304
60548
|
}
|
|
60549
|
+
function ExportSelectCell({ device, checked, onToggle }) {
|
|
60550
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
60551
|
+
type: "checkbox",
|
|
60552
|
+
checked,
|
|
60553
|
+
onChange: onToggle,
|
|
60554
|
+
onClick: (e) => e.stopPropagation(),
|
|
60555
|
+
"aria-label": useUiText()("uiLibrary.deviceExport.select", "Select {{name}}", { name: useDeviceLabel(device, "compact") })
|
|
60556
|
+
});
|
|
60557
|
+
}
|
|
59305
60558
|
/**
|
|
59306
60559
|
* Per-row Expose/Exposed toggle. Reflects whether the row's device is exposed
|
|
59307
60560
|
* to THIS exporter and flips it through the SAME runner the bulk buttons use —
|
|
@@ -59313,6 +60566,7 @@ function DeviceExportSetup({ addonId }) {
|
|
|
59313
60566
|
*/
|
|
59314
60567
|
function ExportRowToggle({ addonId, device, exposed, busy, onToggle }) {
|
|
59315
60568
|
const t = useUiText();
|
|
60569
|
+
const deviceLabel = useDeviceLabel(device, "compact");
|
|
59316
60570
|
const handleClick = (e) => {
|
|
59317
60571
|
e.stopPropagation();
|
|
59318
60572
|
if (busy) return;
|
|
@@ -59323,7 +60577,7 @@ function ExportRowToggle({ addonId, device, exposed, busy, onToggle }) {
|
|
|
59323
60577
|
variant: exposed ? "ghost" : "primary",
|
|
59324
60578
|
disabled: busy,
|
|
59325
60579
|
onClick: handleClick,
|
|
59326
|
-
"aria-label": exposed ? t("uiLibrary.deviceExport.unexposeDevice", "Unexpose {{name}}", { name:
|
|
60580
|
+
"aria-label": exposed ? t("uiLibrary.deviceExport.unexposeDevice", "Unexpose {{name}}", { name: deviceLabel }) : t("uiLibrary.deviceExport.exposeDevice", "Expose {{name}}", { name: deviceLabel }),
|
|
59327
60581
|
title: exposed ? t("uiLibrary.deviceExport.stopTitle", "Stop exposing to \"{{addon}}\"", { addon: addonId }) : t("uiLibrary.deviceExport.exposeTitle", "Expose to \"{{addon}}\"", { addon: addonId }),
|
|
59328
60582
|
children: exposed ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Unlink2, { className: "mr-1 h-3.5 w-3.5" }), t("uiLibrary.deviceExport.exposed", "Exposed")] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Share2, { className: "mr-1 h-3.5 w-3.5" }), t("uiLibrary.deviceExport.expose", "Expose")] })
|
|
59329
60583
|
});
|
|
@@ -59539,12 +60793,10 @@ function DeviceExportPanel({ addonId, onOpenDevice, showSetup = true }) {
|
|
|
59539
60793
|
key: "select",
|
|
59540
60794
|
header: "",
|
|
59541
60795
|
headerClassName: "w-8",
|
|
59542
|
-
cell: (device) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
59543
|
-
|
|
60796
|
+
cell: (device) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExportSelectCell, {
|
|
60797
|
+
device,
|
|
59544
60798
|
checked: selectedIds.has(String(device.id)),
|
|
59545
|
-
|
|
59546
|
-
onClick: (e) => e.stopPropagation(),
|
|
59547
|
-
"aria-label": t("uiLibrary.deviceExport.select", "Select {{name}}", { name: device.name })
|
|
60799
|
+
onToggle: () => toggleSelection(String(device.id))
|
|
59548
60800
|
})
|
|
59549
60801
|
},
|
|
59550
60802
|
{
|
|
@@ -59563,9 +60815,10 @@ function DeviceExportPanel({ addonId, onOpenDevice, showSetup = true }) {
|
|
|
59563
60815
|
{
|
|
59564
60816
|
key: "name",
|
|
59565
60817
|
header: t("uiLibrary.deviceExport.colName", "Name"),
|
|
59566
|
-
cell: (device) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
59567
|
-
|
|
59568
|
-
|
|
60818
|
+
cell: (device) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceName, {
|
|
60819
|
+
device,
|
|
60820
|
+
form: "compact",
|
|
60821
|
+
className: "text-xs font-medium text-foreground"
|
|
59569
60822
|
})
|
|
59570
60823
|
},
|
|
59571
60824
|
{
|
|
@@ -61148,28 +62401,61 @@ function FormField$1({ label, description, error, required, children, orientatio
|
|
|
61148
62401
|
}
|
|
61149
62402
|
//#endregion
|
|
61150
62403
|
//#region src/composites/grouped-tile-picker.tsx
|
|
62404
|
+
/**
|
|
62405
|
+
* `GroupedTilePicker` — choose ONE "type of thing" from tiles grouped by who
|
|
62406
|
+
* provides it (an AI profile kind, a notification-target kind…): an uppercase
|
|
62407
|
+
* group label, then a grid of icon + label tiles. The pre-modal of a
|
|
62408
|
+
* create-flow whose form depends on the choice.
|
|
62409
|
+
*
|
|
62410
|
+
* The tile is deliberately not a `Button`: a vertical icon-over-label card in
|
|
62411
|
+
* a grid, which toolbar-button chrome fights. One place owns that look so the
|
|
62412
|
+
* pickers stay identical.
|
|
62413
|
+
*/
|
|
61151
62414
|
function GroupedTilePicker({ groups, onPick, emptyMessage }) {
|
|
62415
|
+
const [openKey, setOpenKey] = (0, react$1.useState)(null);
|
|
62416
|
+
const openTile = openKey === null ? null : groups.flatMap((group) => group.tiles).find((tile) => tile.key === openKey) ?? null;
|
|
61152
62417
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
61153
62418
|
className: "space-y-4",
|
|
61154
|
-
children: [
|
|
61155
|
-
|
|
61156
|
-
|
|
61157
|
-
|
|
61158
|
-
|
|
61159
|
-
children:
|
|
61160
|
-
|
|
61161
|
-
|
|
61162
|
-
|
|
61163
|
-
|
|
61164
|
-
|
|
61165
|
-
|
|
61166
|
-
|
|
61167
|
-
|
|
61168
|
-
|
|
61169
|
-
|
|
61170
|
-
|
|
61171
|
-
|
|
61172
|
-
|
|
62419
|
+
children: [
|
|
62420
|
+
groups.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
62421
|
+
className: "text-xs text-foreground-subtle",
|
|
62422
|
+
children: emptyMessage
|
|
62423
|
+
}),
|
|
62424
|
+
groups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
62425
|
+
className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-foreground-subtle",
|
|
62426
|
+
children: group.label
|
|
62427
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
62428
|
+
className: "grid grid-cols-2 gap-2 sm:grid-cols-3",
|
|
62429
|
+
children: group.tiles.map((tile) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
62430
|
+
className: "relative",
|
|
62431
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
62432
|
+
type: "button",
|
|
62433
|
+
"data-testid": tile.testId,
|
|
62434
|
+
onClick: () => onPick(tile.key),
|
|
62435
|
+
className: "flex h-full w-full flex-col items-center gap-1.5 rounded-lg border border-border bg-surface px-3 py-3 text-xs transition-colors hover:border-primary/50 hover:bg-surface-hover",
|
|
62436
|
+
children: [tile.icon, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
62437
|
+
className: "text-center font-medium text-foreground",
|
|
62438
|
+
children: tile.label
|
|
62439
|
+
})]
|
|
62440
|
+
}), tile.detail !== void 0 && tile.detailLabel !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
62441
|
+
className: "absolute top-1 right-1",
|
|
62442
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconButton, {
|
|
62443
|
+
type: "button",
|
|
62444
|
+
variant: "ghost",
|
|
62445
|
+
size: "sm",
|
|
62446
|
+
icon: Info,
|
|
62447
|
+
"aria-label": tile.detailLabel,
|
|
62448
|
+
onClick: () => setOpenKey((current) => current === tile.key ? null : tile.key)
|
|
62449
|
+
})
|
|
62450
|
+
})]
|
|
62451
|
+
}, tile.key))
|
|
62452
|
+
})] }, group.id)),
|
|
62453
|
+
openTile?.detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BottomSheet, {
|
|
62454
|
+
open: true,
|
|
62455
|
+
onClose: () => setOpenKey(null),
|
|
62456
|
+
children: openTile.detail
|
|
62457
|
+
})
|
|
62458
|
+
]
|
|
61173
62459
|
});
|
|
61174
62460
|
}
|
|
61175
62461
|
//#endregion
|
|
@@ -66345,6 +67631,26 @@ function deviceGroupTitle(group, t = defaultUiText) {
|
|
|
66345
67631
|
function isDeviceNoun(noun) {
|
|
66346
67632
|
return noun === "camera" || noun === "device";
|
|
66347
67633
|
}
|
|
67634
|
+
/** Compact label for a device id. String ids (nodes, packages) keep the stored text. */
|
|
67635
|
+
function usePickerDeviceLabel(id, stored) {
|
|
67636
|
+
const lookedUp = useDeviceLabelById(typeof id === "number" ? id : 0, "compact", stored);
|
|
67637
|
+
return typeof id === "number" ? lookedUp : stored;
|
|
67638
|
+
}
|
|
67639
|
+
function PickerDeviceName({ id, stored, className }) {
|
|
67640
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
67641
|
+
className,
|
|
67642
|
+
children: usePickerDeviceLabel(id, stored)
|
|
67643
|
+
});
|
|
67644
|
+
}
|
|
67645
|
+
function PickerChip({ id, stored, removed, onRemove }) {
|
|
67646
|
+
const label = usePickerDeviceLabel(id, stored);
|
|
67647
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectedChip, {
|
|
67648
|
+
testId: `picker-chip-${String(id)}`,
|
|
67649
|
+
label,
|
|
67650
|
+
warning: removed,
|
|
67651
|
+
...onRemove !== void 0 ? { onRemove } : {}
|
|
67652
|
+
});
|
|
67653
|
+
}
|
|
66348
67654
|
function chipsOf(value, devices, fleet, noun, t) {
|
|
66349
67655
|
const byId = new Map(devices.map((device) => [device.id, device.name]));
|
|
66350
67656
|
const orphans = new Map(offListSelections(value, devices, fleet.devices, fleet.state).map((row) => [row.id, row]));
|
|
@@ -66380,7 +67686,7 @@ function DevicePicker({ devices: devicesIn, listState, fleet, value, onChange, s
|
|
|
66380
67686
|
const t = useUiText();
|
|
66381
67687
|
const groupTitle = groupTitleProp ?? ((group) => deviceGroupTitle(group, t));
|
|
66382
67688
|
const lockedNote = lockedNoteProp ?? t("uiLibrary.devicePicker.alreadyAdded", "Already added");
|
|
66383
|
-
const devices = (0, react$1.useMemo)(() => withResolvedParentDetail(devicesIn), [devicesIn]);
|
|
67689
|
+
const devices = (0, react$1.useMemo)(() => isDeviceNoun(noun) ? devicesIn : withResolvedParentDetail(devicesIn), [devicesIn, noun]);
|
|
66384
67690
|
const judge = fleet ?? {
|
|
66385
67691
|
state: listState,
|
|
66386
67692
|
devices: listState === "answered" ? devices : void 0
|
|
@@ -66415,10 +67721,10 @@ function DevicePicker({ devices: devicesIn, listState, fleet, value, onChange, s
|
|
|
66415
67721
|
chips.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
66416
67722
|
className: "text-[11px] text-foreground-subtle",
|
|
66417
67723
|
children: emptyLabel ?? (emptyMeansAll ? t("uiLibrary.devicePicker.everyNoRestriction", "Every {{noun}} — no restriction", { noun: pickerNounLabel(noun, t) }) : t("uiLibrary.devicePicker.noneSelected", "None selected"))
|
|
66418
|
-
}) : overflow.shown.map((chip) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
66419
|
-
|
|
66420
|
-
|
|
66421
|
-
|
|
67724
|
+
}) : overflow.shown.map((chip) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PickerChip, {
|
|
67725
|
+
id: chip.id,
|
|
67726
|
+
stored: chip.label,
|
|
67727
|
+
removed: chip.removed,
|
|
66422
67728
|
...!disabled ? { onRemove: () => onChange(value.filter((id) => id !== chip.id)) } : {}
|
|
66423
67729
|
}, chip.id)),
|
|
66424
67730
|
overflow.hidden > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -66711,9 +68017,10 @@ function PickerRowView({ row, value, onChange, onToggleGroup, annotate, groupTit
|
|
|
66711
68017
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
66712
68018
|
className: "flex min-w-0 flex-1 flex-col",
|
|
66713
68019
|
children: [
|
|
66714
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
66715
|
-
|
|
66716
|
-
|
|
68020
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PickerDeviceName, {
|
|
68021
|
+
id: row.device.id,
|
|
68022
|
+
stored: row.device.name,
|
|
68023
|
+
className: "truncate"
|
|
66717
68024
|
}),
|
|
66718
68025
|
second !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
66719
68026
|
className: "truncate text-[10px] text-foreground-subtle",
|
|
@@ -69804,10 +71111,14 @@ exports.DEVICE_COLUMNS = DEVICE_COLUMNS;
|
|
|
69804
71111
|
exports.DEVICE_EXPORT_PAGE_SIZE_KEY = DEVICE_EXPORT_PAGE_SIZE_KEY;
|
|
69805
71112
|
exports.DEVICE_LIST_PAGE_SIZE_KEY = DEVICE_LIST_PAGE_SIZE_KEY;
|
|
69806
71113
|
exports.DEVICE_LIST_PAGE_SIZE_OPTIONS = DEVICE_LIST_PAGE_SIZE_OPTIONS;
|
|
71114
|
+
exports.DEVICE_NAME_FORMS = DEVICE_NAME_FORMS;
|
|
71115
|
+
exports.DEVICE_NAME_JOIN = DEVICE_NAME_JOIN;
|
|
69807
71116
|
exports.DEVICE_PICKER_GROUP_STORAGE_KEY = DEVICE_PICKER_GROUP_STORAGE_KEY;
|
|
69808
71117
|
exports.DEVICE_ROLE_META = DEVICE_ROLE_META;
|
|
71118
|
+
exports.DEVICE_ROLE_NOUNS = DEVICE_ROLE_NOUNS;
|
|
69809
71119
|
exports.DEVICE_TYPE_CONTROL = DEVICE_TYPE_CONTROL;
|
|
69810
71120
|
exports.DEVICE_TYPE_META = DEVICE_TYPE_META;
|
|
71121
|
+
exports.DEVICE_TYPE_NOUNS = DEVICE_TYPE_NOUNS;
|
|
69811
71122
|
exports.DataRecordsHub = DataRecordsHub;
|
|
69812
71123
|
exports.DataTable = DataTable;
|
|
69813
71124
|
exports.DataTableFilterBar = DataTableFilterBar;
|
|
@@ -69824,11 +71135,14 @@ exports.DeviceContextProvider = DeviceContextProvider;
|
|
|
69824
71135
|
exports.DeviceExportPanel = DeviceExportPanel;
|
|
69825
71136
|
exports.DeviceExportSetup = DeviceExportSetup;
|
|
69826
71137
|
exports.DeviceFilterBar = DeviceFilterBar;
|
|
71138
|
+
exports.DeviceFleetFromServer = DeviceFleetFromServer;
|
|
71139
|
+
exports.DeviceFleetProvider = DeviceFleetProvider;
|
|
69827
71140
|
exports.DeviceGrid = DeviceGrid;
|
|
69828
71141
|
exports.DeviceHistoryView = DeviceHistoryView;
|
|
69829
71142
|
exports.DeviceItem = DeviceItem;
|
|
69830
71143
|
exports.DeviceList = DeviceList;
|
|
69831
71144
|
exports.DeviceMultiSelectField = DeviceMultiSelectField;
|
|
71145
|
+
exports.DeviceName = DeviceName;
|
|
69832
71146
|
exports.DevicePicker = DevicePicker;
|
|
69833
71147
|
exports.DeviceQuickDetailProvider = DeviceQuickDetailProvider;
|
|
69834
71148
|
exports.DeviceSelectField = DeviceSelectField;
|
|
@@ -70257,6 +71571,7 @@ exports.ViewSwitch = ViewSwitch;
|
|
|
70257
71571
|
exports.VodPlaybackProvider = VodPlaybackProvider;
|
|
70258
71572
|
exports.Volume2 = Volume2;
|
|
70259
71573
|
exports.VolumeX = VolumeX;
|
|
71574
|
+
exports.WashingMachine = WashingMachine;
|
|
70260
71575
|
exports.WaterHeaterHeroCard = WaterHeaterHeroCard;
|
|
70261
71576
|
exports.WaterHeaterInlineControl = WaterHeaterInlineControl;
|
|
70262
71577
|
exports.Waves = Waves;
|
|
@@ -70359,6 +71674,7 @@ exports.describeDeviceSelector = describeDeviceSelector;
|
|
|
70359
71674
|
exports.deviceIntegrationResolver = deviceIntegrationResolver;
|
|
70360
71675
|
exports.deviceListStateOf = deviceListStateOf;
|
|
70361
71676
|
exports.deviceMatchesFilter = deviceMatchesFilter;
|
|
71677
|
+
exports.deviceNameNouns = deviceNameNouns;
|
|
70362
71678
|
exports.deviceOptionLabel = deviceOptionLabel;
|
|
70363
71679
|
exports.deviceRoleMeta = deviceRoleMeta;
|
|
70364
71680
|
exports.deviceRoleMetaOf = deviceRoleMetaOf;
|
|
@@ -70386,10 +71702,12 @@ exports.findTimezone = _camstack_types.findTimezone;
|
|
|
70386
71702
|
exports.flattenPickerGrouping = flattenPickerGrouping;
|
|
70387
71703
|
exports.flattenPickerRows = flattenPickerRows;
|
|
70388
71704
|
exports.fleetViewOf = fleetViewOf;
|
|
71705
|
+
exports.foldDeviceName = foldDeviceName;
|
|
70389
71706
|
exports.formatChartBytes = formatChartBytes;
|
|
70390
71707
|
exports.formatChartNumber = formatChartNumber;
|
|
70391
71708
|
exports.formatChartValue = formatChartValue;
|
|
70392
71709
|
exports.formatControlDateTime = formatControlDateTime;
|
|
71710
|
+
exports.formatDeviceName = formatDeviceName;
|
|
70393
71711
|
exports.formatLastSeen = formatLastSeen;
|
|
70394
71712
|
exports.formatNumeric = formatNumeric;
|
|
70395
71713
|
exports.formatSettingValue = formatSettingValue;
|
|
@@ -70417,6 +71735,7 @@ exports.humanizeName = humanizeName;
|
|
|
70417
71735
|
exports.humidifierTint = humidifierTint;
|
|
70418
71736
|
exports.iconGlyphsFailed = iconGlyphsFailed;
|
|
70419
71737
|
exports.iconGlyphsLoaded = iconGlyphsLoaded;
|
|
71738
|
+
exports.indexDeviceNames = indexDeviceNames;
|
|
70420
71739
|
exports.initialScrubState = initialScrubState;
|
|
70421
71740
|
exports.insertAtSelection = insertAtSelection;
|
|
70422
71741
|
exports.isAbsentProvider = isAbsentProvider;
|
|
@@ -70424,6 +71743,7 @@ exports.isAbsentProvider$1 = isAbsentProvider;
|
|
|
70424
71743
|
exports.isByteUnit = isByteUnit;
|
|
70425
71744
|
exports.isConsumableLevelField = isConsumableLevelField;
|
|
70426
71745
|
exports.isDataTableFilterActive = isDataTableFilterActive;
|
|
71746
|
+
exports.isDeviceNameStock = isDeviceNameStock;
|
|
70427
71747
|
Object.defineProperty(exports, "isDrawableSubjectPath", {
|
|
70428
71748
|
enumerable: true,
|
|
70429
71749
|
get: function() {
|
|
@@ -70465,6 +71785,7 @@ exports.nodeTextColorClass = nodeTextColorClass;
|
|
|
70465
71785
|
exports.normalizeForSearch = normalizeForSearch;
|
|
70466
71786
|
exports.normalizeLanguage = normalizeLanguage;
|
|
70467
71787
|
exports.normalizeSelection = normalizeSelection;
|
|
71788
|
+
exports.nounSpecFor = nounSpecFor;
|
|
70468
71789
|
exports.occupancyFacets = occupancyFacets;
|
|
70469
71790
|
exports.occupancyLines = occupancyLines;
|
|
70470
71791
|
exports.offListSelections = offListSelections;
|
|
@@ -70519,6 +71840,7 @@ exports.resolveContainerPrimary = resolveContainerPrimary;
|
|
|
70519
71840
|
exports.resolveControlAlign = resolveControlAlign;
|
|
70520
71841
|
exports.resolveDeviceControl = resolveDeviceControl;
|
|
70521
71842
|
exports.resolveDeviceIntegration = resolveDeviceIntegration;
|
|
71843
|
+
exports.resolveDeviceLabel = resolveDeviceLabel;
|
|
70522
71844
|
exports.resolveDisplayIcon = resolveDisplayIcon;
|
|
70523
71845
|
exports.resolveEffectiveDefaultModel = resolveEffectiveDefaultModel;
|
|
70524
71846
|
exports.resolveEffectiveStepModel = resolveEffectiveStepModel;
|
|
@@ -70537,6 +71859,7 @@ exports.rootSourceState = rootSourceState;
|
|
|
70537
71859
|
exports.routerBasename = routerBasename;
|
|
70538
71860
|
exports.runningDurationSince = runningDurationSince;
|
|
70539
71861
|
exports.runningStatusParts = runningStatusParts;
|
|
71862
|
+
exports.sameDeviceName = sameDeviceName;
|
|
70540
71863
|
exports.sameLocationSuggestions = sameLocationSuggestions;
|
|
70541
71864
|
exports.scrubReducer = scrubReducer;
|
|
70542
71865
|
exports.searchSteps = searchSteps;
|
|
@@ -70570,6 +71893,7 @@ exports.stepFieldDomId = stepFieldDomId;
|
|
|
70570
71893
|
exports.stepHasModelForFormat = stepHasModelForFormat;
|
|
70571
71894
|
exports.stepLocalFields = stepLocalFields;
|
|
70572
71895
|
exports.stepModelOptions = stepModelOptions;
|
|
71896
|
+
exports.stripDeviceParentPrefix = stripDeviceParentPrefix;
|
|
70573
71897
|
exports.stripParentNamePrefix = stripParentNamePrefix;
|
|
70574
71898
|
Object.defineProperty(exports, "subjectPathSampleFromBox", {
|
|
70575
71899
|
enumerable: true,
|
|
@@ -70867,6 +72191,8 @@ exports.useDeviceHistoryRecord = useDeviceHistoryRecord;
|
|
|
70867
72191
|
exports.useDeviceHistoryRecordBuckets = useDeviceHistoryRecordBuckets;
|
|
70868
72192
|
exports.useDeviceHistorySetDeviceEnabled = useDeviceHistorySetDeviceEnabled;
|
|
70869
72193
|
exports.useDeviceId = useDeviceId;
|
|
72194
|
+
exports.useDeviceLabel = useDeviceLabel;
|
|
72195
|
+
exports.useDeviceLabelById = useDeviceLabelById;
|
|
70870
72196
|
exports.useDeviceListPageSize = useDeviceListPageSize;
|
|
70871
72197
|
exports.useDeviceManagerAddLocation = useDeviceManagerAddLocation;
|
|
70872
72198
|
exports.useDeviceManagerAdoptDevice = useDeviceManagerAdoptDevice;
|
|
@@ -70960,6 +72286,8 @@ exports.useDeviceManagerTestField = useDeviceManagerTestField;
|
|
|
70960
72286
|
exports.useDeviceManagerUpdateConfig = useDeviceManagerUpdateConfig;
|
|
70961
72287
|
exports.useDeviceManagerUpdateDeviceField = useDeviceManagerUpdateDeviceField;
|
|
70962
72288
|
exports.useDeviceManagerUpdateDeviceFieldsBatch = useDeviceManagerUpdateDeviceFieldsBatch;
|
|
72289
|
+
exports.useDeviceNameIndex = useDeviceNameIndex;
|
|
72290
|
+
exports.useDeviceNameNouns = useDeviceNameNouns;
|
|
70963
72291
|
exports.useDeviceNetworkLink = useDeviceNetworkLink;
|
|
70964
72292
|
exports.useDeviceOpsGetConfigEntries = useDeviceOpsGetConfigEntries;
|
|
70965
72293
|
exports.useDeviceOpsGetRawState = useDeviceOpsGetRawState;
|