@camstack/ui-library 1.2.122 → 1.2.123

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.
@@ -22,5 +22,18 @@ export declare function RecordingBandsEditor({ bands, onChange, sensorContext, }
22
22
  export interface RecordingSensorContext {
23
23
  readonly cameraId: number;
24
24
  readonly location: string | null;
25
+ /**
26
+ * Does this camera publish its own `recording-signal` — the LEVEL an events
27
+ * band can follow (`RecordingTriggers.deviceSignal`)? Asked of the camera's
28
+ * bindings by the host. Absent = the host did not ask; the control is then
29
+ * offered only to switch OFF a band that already listens.
30
+ */
31
+ readonly deviceSignal?: DeviceSignalPresence;
25
32
  }
33
+ /**
34
+ * What the host knows about the camera's `recording-signal` binding. Four
35
+ * states, not a boolean (D315): `pending` and `unknown` must render as
36
+ * "not yet known", never as "this camera has no signal".
37
+ */
38
+ export type DeviceSignalPresence = 'pending' | 'present' | 'absent' | 'unknown';
26
39
  export {};
package/dist/index.cjs CHANGED
@@ -17412,6 +17412,11 @@ function BandRow({ band, onChange, onRemove, sensorContext }) {
17412
17412
  }, cls);
17413
17413
  })]
17414
17414
  }),
17415
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceSignalTrigger, {
17416
+ presence: sensorContext?.deviceSignal,
17417
+ checked: band.triggers?.deviceSignal === true,
17418
+ onChange: (on) => setTriggers({ deviceSignal: on ? true : void 0 })
17419
+ }),
17415
17420
  sensorContext !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceMultiSelectField, {
17416
17421
  field: sensorPickerField(sensorContext),
17417
17422
  value: (band.triggers?.sensorDeviceIds ?? []).map(String),
@@ -17457,6 +17462,34 @@ function BandRow({ band, onChange, onRemove, sensorContext }) {
17457
17462
  ]
17458
17463
  });
17459
17464
  }
17465
+ /**
17466
+ * The `deviceSignal` control. Offered when the camera is KNOWN to publish the
17467
+ * signal; shown disabled while that is not yet known (a control that vanishes
17468
+ * while a query is in flight reads as "this camera cannot do it"); and, for a
17469
+ * band that already listens, always offered so the operator can switch it
17470
+ * off — whatever the host knows today.
17471
+ */
17472
+ function DeviceSignalTrigger({ presence, checked, onChange }) {
17473
+ const settled = presence === "present" || checked;
17474
+ if (!settled && presence !== "pending" && presence !== "unknown") return null;
17475
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
17476
+ className: "flex items-center gap-2 text-xs",
17477
+ children: [
17478
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
17479
+ type: "checkbox",
17480
+ "aria-label": "Device signal",
17481
+ checked,
17482
+ disabled: !settled,
17483
+ onChange: (e) => onChange(e.target.checked)
17484
+ }),
17485
+ "Device signal",
17486
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
17487
+ className: "text-foreground-subtle",
17488
+ children: presence === "pending" ? "checking the camera…" : presence === "unknown" ? "could not check the camera" : presence === "absent" ? "not offered by this camera" : "records for as long as the device reports it is in function"
17489
+ })
17490
+ ]
17491
+ });
17492
+ }
17460
17493
  //#endregion
17461
17494
  //#region src/composites/cap-settings/RecordingSettings.tsx
17462
17495
  var MODES = [
@@ -19152,6 +19185,8 @@ function RecordingPanel({ deviceId }) {
19152
19185
  const statusQuery = useRecordingGetStatus({ deviceId });
19153
19186
  const configQuery = useRecordingGetDeviceConfig({ deviceId });
19154
19187
  const cameraLocation = useDeviceManagerGetDevice({ deviceId }).data?.location ?? null;
19188
+ const bindingsQuery = useDeviceManagerGetBindings({ deviceId });
19189
+ const deviceSignal = bindingsQuery.status === "pending" ? "pending" : bindingsQuery.status === "error" ? "unknown" : bindingsQuery.data.entries.some((e) => e.capName === "recording-signal") ? "present" : "absent";
19155
19190
  const setConfig = useRecordingSetDeviceConfig();
19156
19191
  const rescanStorage = useRecordingRescanStorage();
19157
19192
  const { data: profileSlots } = useStreamBrokerListAllProfileSlots(void 0, { staleTime: 3e4 });
@@ -19199,7 +19234,8 @@ function RecordingPanel({ deviceId }) {
19199
19234
  onSave: saveConfig,
19200
19235
  sensorContext: {
19201
19236
  cameraId: deviceId,
19202
- location: cameraLocation
19237
+ location: cameraLocation,
19238
+ deviceSignal
19203
19239
  }
19204
19240
  }, JSON.stringify(resolvedConfig)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
19205
19241
  className: "px-1 py-2 text-xs text-foreground-subtle",
package/dist/index.js CHANGED
@@ -17388,6 +17388,11 @@ function BandRow({ band, onChange, onRemove, sensorContext }) {
17388
17388
  }, cls);
17389
17389
  })]
17390
17390
  }),
17391
+ /* @__PURE__ */ jsx(DeviceSignalTrigger, {
17392
+ presence: sensorContext?.deviceSignal,
17393
+ checked: band.triggers?.deviceSignal === true,
17394
+ onChange: (on) => setTriggers({ deviceSignal: on ? true : void 0 })
17395
+ }),
17391
17396
  sensorContext !== void 0 ? /* @__PURE__ */ jsx(DeviceMultiSelectField, {
17392
17397
  field: sensorPickerField(sensorContext),
17393
17398
  value: (band.triggers?.sensorDeviceIds ?? []).map(String),
@@ -17433,6 +17438,34 @@ function BandRow({ band, onChange, onRemove, sensorContext }) {
17433
17438
  ]
17434
17439
  });
17435
17440
  }
17441
+ /**
17442
+ * The `deviceSignal` control. Offered when the camera is KNOWN to publish the
17443
+ * signal; shown disabled while that is not yet known (a control that vanishes
17444
+ * while a query is in flight reads as "this camera cannot do it"); and, for a
17445
+ * band that already listens, always offered so the operator can switch it
17446
+ * off — whatever the host knows today.
17447
+ */
17448
+ function DeviceSignalTrigger({ presence, checked, onChange }) {
17449
+ const settled = presence === "present" || checked;
17450
+ if (!settled && presence !== "pending" && presence !== "unknown") return null;
17451
+ return /* @__PURE__ */ jsxs("label", {
17452
+ className: "flex items-center gap-2 text-xs",
17453
+ children: [
17454
+ /* @__PURE__ */ jsx("input", {
17455
+ type: "checkbox",
17456
+ "aria-label": "Device signal",
17457
+ checked,
17458
+ disabled: !settled,
17459
+ onChange: (e) => onChange(e.target.checked)
17460
+ }),
17461
+ "Device signal",
17462
+ /* @__PURE__ */ jsx("span", {
17463
+ className: "text-foreground-subtle",
17464
+ children: presence === "pending" ? "checking the camera…" : presence === "unknown" ? "could not check the camera" : presence === "absent" ? "not offered by this camera" : "records for as long as the device reports it is in function"
17465
+ })
17466
+ ]
17467
+ });
17468
+ }
17436
17469
  //#endregion
17437
17470
  //#region src/composites/cap-settings/RecordingSettings.tsx
17438
17471
  var MODES = [
@@ -19128,6 +19161,8 @@ function RecordingPanel({ deviceId }) {
19128
19161
  const statusQuery = useRecordingGetStatus({ deviceId });
19129
19162
  const configQuery = useRecordingGetDeviceConfig({ deviceId });
19130
19163
  const cameraLocation = useDeviceManagerGetDevice({ deviceId }).data?.location ?? null;
19164
+ const bindingsQuery = useDeviceManagerGetBindings({ deviceId });
19165
+ const deviceSignal = bindingsQuery.status === "pending" ? "pending" : bindingsQuery.status === "error" ? "unknown" : bindingsQuery.data.entries.some((e) => e.capName === "recording-signal") ? "present" : "absent";
19131
19166
  const setConfig = useRecordingSetDeviceConfig();
19132
19167
  const rescanStorage = useRecordingRescanStorage();
19133
19168
  const { data: profileSlots } = useStreamBrokerListAllProfileSlots(void 0, { staleTime: 3e4 });
@@ -19175,7 +19210,8 @@ function RecordingPanel({ deviceId }) {
19175
19210
  onSave: saveConfig,
19176
19211
  sensorContext: {
19177
19212
  cameraId: deviceId,
19178
- location: cameraLocation
19213
+ location: cameraLocation,
19214
+ deviceSignal
19179
19215
  }
19180
19216
  }, JSON.stringify(resolvedConfig)) : /* @__PURE__ */ jsx("div", {
19181
19217
  className: "px-1 py-2 text-xs text-foreground-subtle",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/ui-library",
3
- "version": "1.2.122",
3
+ "version": "1.2.123",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",