@camstack/ui-library 1.2.248 → 1.2.249
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/composites/config-icon-field.d.ts +11 -0
- package/dist/composites/device-export-panel.d.ts +19 -1
- package/dist/composites/device-list/generic-mode.d.ts +12 -0
- package/dist/composites/device-list/index.d.ts +2 -1
- package/dist/composites/device-list/page-size-select.d.ts +10 -0
- package/dist/composites/index.d.ts +1 -1
- package/dist/generated/system-hooks.d.ts +12 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/use-device-list-page-size.d.ts +2 -1
- package/dist/hooks/use-persisted-page-size.d.ts +18 -0
- package/dist/index.cjs +1118 -910
- package/dist/index.js +1588 -1393
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -29,9 +29,9 @@ let _trpc_react_query = require("@trpc/react-query");
|
|
|
29
29
|
_trpc_react_query = __toESM(_trpc_react_query, 1);
|
|
30
30
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
31
31
|
react_jsx_runtime = __toESM(react_jsx_runtime, 1);
|
|
32
|
+
let _camstack_types = require("@camstack/types");
|
|
32
33
|
let react_dom = require("react-dom");
|
|
33
34
|
react_dom = __toESM(react_dom, 1);
|
|
34
|
-
let _camstack_types = require("@camstack/types");
|
|
35
35
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
36
36
|
_tanstack_react_query = __toESM(_tanstack_react_query, 1);
|
|
37
37
|
let react_dom_client = require("react-dom/client");
|
|
@@ -6466,151 +6466,901 @@ function useClusterNodes() {
|
|
|
6466
6466
|
};
|
|
6467
6467
|
}
|
|
6468
6468
|
//#endregion
|
|
6469
|
-
//#region src/
|
|
6469
|
+
//#region src/composites/device-meta.ts
|
|
6470
|
+
var DEVICE_TYPE_META = {
|
|
6471
|
+
[_camstack_types.DeviceType.Camera]: {
|
|
6472
|
+
icon: Camera,
|
|
6473
|
+
label: "Camera"
|
|
6474
|
+
},
|
|
6475
|
+
[_camstack_types.DeviceType.Hub]: {
|
|
6476
|
+
icon: Network,
|
|
6477
|
+
label: "Hub"
|
|
6478
|
+
},
|
|
6479
|
+
[_camstack_types.DeviceType.Light]: {
|
|
6480
|
+
icon: Lightbulb,
|
|
6481
|
+
label: "Light"
|
|
6482
|
+
},
|
|
6483
|
+
[_camstack_types.DeviceType.Siren]: {
|
|
6484
|
+
icon: Siren,
|
|
6485
|
+
label: "Siren"
|
|
6486
|
+
},
|
|
6487
|
+
[_camstack_types.DeviceType.Switch]: {
|
|
6488
|
+
icon: ToggleLeft,
|
|
6489
|
+
label: "Switch"
|
|
6490
|
+
},
|
|
6491
|
+
[_camstack_types.DeviceType.Sensor]: {
|
|
6492
|
+
icon: Activity,
|
|
6493
|
+
label: "Sensor"
|
|
6494
|
+
},
|
|
6495
|
+
[_camstack_types.DeviceType.Thermostat]: {
|
|
6496
|
+
icon: Thermometer,
|
|
6497
|
+
label: "Thermostat"
|
|
6498
|
+
},
|
|
6499
|
+
[_camstack_types.DeviceType.Climate]: {
|
|
6500
|
+
icon: AirVent,
|
|
6501
|
+
label: "Air conditioner"
|
|
6502
|
+
},
|
|
6503
|
+
[_camstack_types.DeviceType.Button]: {
|
|
6504
|
+
icon: CircleDot,
|
|
6505
|
+
label: "Button"
|
|
6506
|
+
},
|
|
6507
|
+
[_camstack_types.DeviceType.EventEmitter]: {
|
|
6508
|
+
icon: Zap,
|
|
6509
|
+
label: "Event Emitter"
|
|
6510
|
+
},
|
|
6511
|
+
[_camstack_types.DeviceType.Update]: {
|
|
6512
|
+
icon: RefreshCw,
|
|
6513
|
+
label: "Update"
|
|
6514
|
+
},
|
|
6515
|
+
[_camstack_types.DeviceType.Generic]: {
|
|
6516
|
+
icon: Box,
|
|
6517
|
+
label: "Generic"
|
|
6518
|
+
},
|
|
6519
|
+
[_camstack_types.DeviceType.Notifier]: {
|
|
6520
|
+
icon: Bell,
|
|
6521
|
+
label: "Notifier"
|
|
6522
|
+
},
|
|
6523
|
+
[_camstack_types.DeviceType.Script]: {
|
|
6524
|
+
icon: ScrollText,
|
|
6525
|
+
label: "Script"
|
|
6526
|
+
},
|
|
6527
|
+
[_camstack_types.DeviceType.Automation]: {
|
|
6528
|
+
icon: Workflow,
|
|
6529
|
+
label: "Automation"
|
|
6530
|
+
},
|
|
6531
|
+
[_camstack_types.DeviceType.Lock]: {
|
|
6532
|
+
icon: Lock,
|
|
6533
|
+
label: "Lock"
|
|
6534
|
+
},
|
|
6535
|
+
[_camstack_types.DeviceType.Cover]: {
|
|
6536
|
+
icon: Blinds,
|
|
6537
|
+
label: "Cover"
|
|
6538
|
+
},
|
|
6539
|
+
[_camstack_types.DeviceType.Valve]: {
|
|
6540
|
+
icon: Pipette,
|
|
6541
|
+
label: "Valve"
|
|
6542
|
+
},
|
|
6543
|
+
[_camstack_types.DeviceType.Humidifier]: {
|
|
6544
|
+
icon: Waves,
|
|
6545
|
+
label: "Humidifier"
|
|
6546
|
+
},
|
|
6547
|
+
[_camstack_types.DeviceType.WaterHeater]: {
|
|
6548
|
+
icon: Bath,
|
|
6549
|
+
label: "Water heater"
|
|
6550
|
+
},
|
|
6551
|
+
[_camstack_types.DeviceType.Fan]: {
|
|
6552
|
+
icon: Fan,
|
|
6553
|
+
label: "Fan"
|
|
6554
|
+
},
|
|
6555
|
+
[_camstack_types.DeviceType.MediaPlayer]: {
|
|
6556
|
+
icon: MonitorPlay,
|
|
6557
|
+
label: "Media player"
|
|
6558
|
+
},
|
|
6559
|
+
[_camstack_types.DeviceType.AlarmPanel]: {
|
|
6560
|
+
icon: ShieldAlert,
|
|
6561
|
+
label: "Alarm panel"
|
|
6562
|
+
},
|
|
6563
|
+
[_camstack_types.DeviceType.Control]: {
|
|
6564
|
+
icon: SlidersHorizontal,
|
|
6565
|
+
label: "Control"
|
|
6566
|
+
},
|
|
6567
|
+
[_camstack_types.DeviceType.Presence]: {
|
|
6568
|
+
icon: MapPin,
|
|
6569
|
+
label: "Presence"
|
|
6570
|
+
},
|
|
6571
|
+
[_camstack_types.DeviceType.Weather]: {
|
|
6572
|
+
icon: CloudSun,
|
|
6573
|
+
label: "Weather"
|
|
6574
|
+
},
|
|
6575
|
+
[_camstack_types.DeviceType.Vacuum]: {
|
|
6576
|
+
icon: Bot,
|
|
6577
|
+
label: "Vacuum"
|
|
6578
|
+
},
|
|
6579
|
+
[_camstack_types.DeviceType.LawnMower]: {
|
|
6580
|
+
icon: Tractor,
|
|
6581
|
+
label: "Lawn mower"
|
|
6582
|
+
},
|
|
6583
|
+
[_camstack_types.DeviceType.Container]: {
|
|
6584
|
+
icon: Box,
|
|
6585
|
+
label: "Container"
|
|
6586
|
+
},
|
|
6587
|
+
[_camstack_types.DeviceType.Image]: {
|
|
6588
|
+
icon: Image,
|
|
6589
|
+
label: "Image"
|
|
6590
|
+
},
|
|
6591
|
+
[_camstack_types.DeviceType.PetFeeder]: {
|
|
6592
|
+
icon: Bone,
|
|
6593
|
+
label: "Pet feeder"
|
|
6594
|
+
}
|
|
6595
|
+
};
|
|
6596
|
+
var DEVICE_ROLE_META = {
|
|
6597
|
+
[_camstack_types.DeviceRole.Siren]: {
|
|
6598
|
+
icon: Siren,
|
|
6599
|
+
label: "Siren"
|
|
6600
|
+
},
|
|
6601
|
+
[_camstack_types.DeviceRole.Floodlight]: {
|
|
6602
|
+
icon: Lightbulb,
|
|
6603
|
+
label: "Floodlight"
|
|
6604
|
+
},
|
|
6605
|
+
[_camstack_types.DeviceRole.Spotlight]: {
|
|
6606
|
+
icon: Flashlight,
|
|
6607
|
+
label: "Spotlight"
|
|
6608
|
+
},
|
|
6609
|
+
[_camstack_types.DeviceRole.PirSensor]: {
|
|
6610
|
+
icon: Radar,
|
|
6611
|
+
label: "PIR sensor"
|
|
6612
|
+
},
|
|
6613
|
+
[_camstack_types.DeviceRole.Chime]: {
|
|
6614
|
+
icon: Bell,
|
|
6615
|
+
label: "Chime"
|
|
6616
|
+
},
|
|
6617
|
+
[_camstack_types.DeviceRole.Autotrack]: {
|
|
6618
|
+
icon: Crosshair,
|
|
6619
|
+
label: "Auto-track"
|
|
6620
|
+
},
|
|
6621
|
+
[_camstack_types.DeviceRole.Nightvision]: {
|
|
6622
|
+
icon: Moon,
|
|
6623
|
+
label: "Night vision"
|
|
6624
|
+
},
|
|
6625
|
+
[_camstack_types.DeviceRole.PrivacyMask]: {
|
|
6626
|
+
icon: EyeOff,
|
|
6627
|
+
label: "Privacy mask"
|
|
6628
|
+
},
|
|
6629
|
+
[_camstack_types.DeviceRole.Doorbell]: {
|
|
6630
|
+
icon: DoorClosed,
|
|
6631
|
+
label: "Doorbell"
|
|
6632
|
+
},
|
|
6633
|
+
[_camstack_types.DeviceRole.BinaryHelper]: {
|
|
6634
|
+
icon: ToggleLeft,
|
|
6635
|
+
label: "Binary helper"
|
|
6636
|
+
},
|
|
6637
|
+
[_camstack_types.DeviceRole.MotionSensor]: {
|
|
6638
|
+
icon: Footprints,
|
|
6639
|
+
label: "Motion sensor"
|
|
6640
|
+
},
|
|
6641
|
+
[_camstack_types.DeviceRole.ContactSensor]: {
|
|
6642
|
+
icon: DoorOpen,
|
|
6643
|
+
label: "Contact sensor"
|
|
6644
|
+
},
|
|
6645
|
+
[_camstack_types.DeviceRole.LeakSensor]: {
|
|
6646
|
+
icon: Droplet,
|
|
6647
|
+
label: "Leak sensor"
|
|
6648
|
+
},
|
|
6649
|
+
[_camstack_types.DeviceRole.SmokeSensor]: {
|
|
6650
|
+
icon: AlarmSmoke,
|
|
6651
|
+
label: "Smoke sensor"
|
|
6652
|
+
},
|
|
6653
|
+
[_camstack_types.DeviceRole.COSensor]: {
|
|
6654
|
+
icon: Wind,
|
|
6655
|
+
label: "CO sensor"
|
|
6656
|
+
},
|
|
6657
|
+
[_camstack_types.DeviceRole.GasSensor]: {
|
|
6658
|
+
icon: Flame,
|
|
6659
|
+
label: "Gas sensor"
|
|
6660
|
+
},
|
|
6661
|
+
[_camstack_types.DeviceRole.TamperSensor]: {
|
|
6662
|
+
icon: ShieldAlert,
|
|
6663
|
+
label: "Tamper sensor"
|
|
6664
|
+
},
|
|
6665
|
+
[_camstack_types.DeviceRole.VibrationSensor]: {
|
|
6666
|
+
icon: Vibrate,
|
|
6667
|
+
label: "Vibration sensor"
|
|
6668
|
+
},
|
|
6669
|
+
[_camstack_types.DeviceRole.ConnectivitySensor]: {
|
|
6670
|
+
icon: Wifi,
|
|
6671
|
+
label: "Connectivity"
|
|
6672
|
+
},
|
|
6673
|
+
[_camstack_types.DeviceRole.SoundSensor]: {
|
|
6674
|
+
icon: Volume2,
|
|
6675
|
+
label: "Sound sensor"
|
|
6676
|
+
},
|
|
6677
|
+
[_camstack_types.DeviceRole.BinarySensor]: {
|
|
6678
|
+
icon: ToggleLeft,
|
|
6679
|
+
label: "Binary sensor"
|
|
6680
|
+
},
|
|
6681
|
+
[_camstack_types.DeviceRole.TemperatureSensor]: {
|
|
6682
|
+
icon: Thermometer,
|
|
6683
|
+
label: "Temperature"
|
|
6684
|
+
},
|
|
6685
|
+
[_camstack_types.DeviceRole.HumiditySensor]: {
|
|
6686
|
+
icon: Droplets,
|
|
6687
|
+
label: "Humidity"
|
|
6688
|
+
},
|
|
6689
|
+
[_camstack_types.DeviceRole.AmbientLightSensor]: {
|
|
6690
|
+
icon: Sun,
|
|
6691
|
+
label: "Ambient light"
|
|
6692
|
+
},
|
|
6693
|
+
[_camstack_types.DeviceRole.PressureSensor]: {
|
|
6694
|
+
icon: Gauge,
|
|
6695
|
+
label: "Pressure"
|
|
6696
|
+
},
|
|
6697
|
+
[_camstack_types.DeviceRole.WindSensor]: {
|
|
6698
|
+
icon: Wind,
|
|
6699
|
+
label: "Wind"
|
|
6700
|
+
},
|
|
6701
|
+
[_camstack_types.DeviceRole.RainSensor]: {
|
|
6702
|
+
icon: CloudRain,
|
|
6703
|
+
label: "Rain"
|
|
6704
|
+
},
|
|
6705
|
+
[_camstack_types.DeviceRole.UvSensor]: {
|
|
6706
|
+
icon: SunMedium,
|
|
6707
|
+
label: "UV index"
|
|
6708
|
+
},
|
|
6709
|
+
[_camstack_types.DeviceRole.SolarRadiationSensor]: {
|
|
6710
|
+
icon: Sunrise,
|
|
6711
|
+
label: "Solar radiation"
|
|
6712
|
+
},
|
|
6713
|
+
[_camstack_types.DeviceRole.SoilMoistureSensor]: {
|
|
6714
|
+
icon: Sprout,
|
|
6715
|
+
label: "Soil moisture"
|
|
6716
|
+
},
|
|
6717
|
+
[_camstack_types.DeviceRole.PowerSensor]: {
|
|
6718
|
+
icon: Zap,
|
|
6719
|
+
label: "Power"
|
|
6720
|
+
},
|
|
6721
|
+
[_camstack_types.DeviceRole.EnergySensor]: {
|
|
6722
|
+
icon: Zap,
|
|
6723
|
+
label: "Energy"
|
|
6724
|
+
},
|
|
6725
|
+
[_camstack_types.DeviceRole.VoltageSensor]: {
|
|
6726
|
+
icon: Zap,
|
|
6727
|
+
label: "Voltage"
|
|
6728
|
+
},
|
|
6729
|
+
[_camstack_types.DeviceRole.CurrentSensor]: {
|
|
6730
|
+
icon: Zap,
|
|
6731
|
+
label: "Current"
|
|
6732
|
+
},
|
|
6733
|
+
[_camstack_types.DeviceRole.AirQualitySensor]: {
|
|
6734
|
+
icon: Wind,
|
|
6735
|
+
label: "Air quality"
|
|
6736
|
+
},
|
|
6737
|
+
[_camstack_types.DeviceRole.BatterySensor]: {
|
|
6738
|
+
icon: Gauge,
|
|
6739
|
+
label: "Battery"
|
|
6740
|
+
},
|
|
6741
|
+
[_camstack_types.DeviceRole.NumericSensor]: {
|
|
6742
|
+
icon: Hash,
|
|
6743
|
+
label: "Numeric sensor"
|
|
6744
|
+
},
|
|
6745
|
+
[_camstack_types.DeviceRole.EnumSensor]: {
|
|
6746
|
+
icon: List,
|
|
6747
|
+
label: "Enum sensor"
|
|
6748
|
+
},
|
|
6749
|
+
[_camstack_types.DeviceRole.DateTimeSensor]: {
|
|
6750
|
+
icon: Clock,
|
|
6751
|
+
label: "Date / time"
|
|
6752
|
+
},
|
|
6753
|
+
[_camstack_types.DeviceRole.GenericSensor]: {
|
|
6754
|
+
icon: Gauge,
|
|
6755
|
+
label: "Sensor"
|
|
6756
|
+
},
|
|
6757
|
+
[_camstack_types.DeviceRole.NumericControl]: {
|
|
6758
|
+
icon: SlidersHorizontal,
|
|
6759
|
+
label: "Numeric control"
|
|
6760
|
+
},
|
|
6761
|
+
[_camstack_types.DeviceRole.SelectControl]: {
|
|
6762
|
+
icon: ListChecks,
|
|
6763
|
+
label: "Select control"
|
|
6764
|
+
},
|
|
6765
|
+
[_camstack_types.DeviceRole.TextControl]: {
|
|
6766
|
+
icon: Type,
|
|
6767
|
+
label: "Text control"
|
|
6768
|
+
},
|
|
6769
|
+
[_camstack_types.DeviceRole.DateTimeControl]: {
|
|
6770
|
+
icon: Clock,
|
|
6771
|
+
label: "Date / time control"
|
|
6772
|
+
},
|
|
6773
|
+
[_camstack_types.DeviceRole.MobilePushNotifier]: {
|
|
6774
|
+
icon: Smartphone,
|
|
6775
|
+
label: "Mobile push"
|
|
6776
|
+
},
|
|
6777
|
+
[_camstack_types.DeviceRole.MessagingNotifier]: {
|
|
6778
|
+
icon: MessageSquare,
|
|
6779
|
+
label: "Messaging"
|
|
6780
|
+
},
|
|
6781
|
+
[_camstack_types.DeviceRole.EmailNotifier]: {
|
|
6782
|
+
icon: Mail,
|
|
6783
|
+
label: "Email"
|
|
6784
|
+
},
|
|
6785
|
+
[_camstack_types.DeviceRole.GenericNotifier]: {
|
|
6786
|
+
icon: Bell,
|
|
6787
|
+
label: "Notifier"
|
|
6788
|
+
}
|
|
6789
|
+
};
|
|
6790
|
+
var DEVICE_TYPE_VALUES$1 = new Set(Object.values(_camstack_types.DeviceType));
|
|
6791
|
+
var DEVICE_ROLE_VALUES = new Set(Object.values(_camstack_types.DeviceRole));
|
|
6792
|
+
function isDeviceType(value) {
|
|
6793
|
+
return DEVICE_TYPE_VALUES$1.has(value);
|
|
6794
|
+
}
|
|
6795
|
+
function isDeviceRole(value) {
|
|
6796
|
+
return DEVICE_ROLE_VALUES.has(value);
|
|
6797
|
+
}
|
|
6798
|
+
/** Meta for a known `DeviceType`. */
|
|
6799
|
+
function deviceTypeMeta(type) {
|
|
6800
|
+
return DEVICE_TYPE_META[type];
|
|
6801
|
+
}
|
|
6802
|
+
/** Meta for a known `DeviceRole`. */
|
|
6803
|
+
function deviceRoleMeta(role) {
|
|
6804
|
+
return DEVICE_ROLE_META[role];
|
|
6805
|
+
}
|
|
6806
|
+
var FALLBACK_DEVICE_TYPE_META = DEVICE_TYPE_META[_camstack_types.DeviceType.Generic];
|
|
6807
|
+
var FALLBACK_DEVICE_ROLE_META = DEVICE_ROLE_META[_camstack_types.DeviceRole.GenericSensor];
|
|
6470
6808
|
/**
|
|
6471
|
-
*
|
|
6809
|
+
* Runtime-string-safe lookup: device data crosses process / network boundaries
|
|
6810
|
+
* as plain strings, so an unrecognised value falls back to the `Generic` meta
|
|
6811
|
+
* instead of throwing.
|
|
6472
6812
|
*
|
|
6473
|
-
*
|
|
6474
|
-
*
|
|
6475
|
-
*
|
|
6476
|
-
|
|
6477
|
-
|
|
6813
|
+
* This also guards mixed-version module-federation loads where the host
|
|
6814
|
+
* `@camstack/types` enum has a new member before the loaded ui-library bundle
|
|
6815
|
+
* has the matching `DEVICE_TYPE_META` entry.
|
|
6816
|
+
*/
|
|
6817
|
+
function deviceTypeMetaOf(type) {
|
|
6818
|
+
if (!isDeviceType(type)) return FALLBACK_DEVICE_TYPE_META;
|
|
6819
|
+
return DEVICE_TYPE_META[type] ?? FALLBACK_DEVICE_TYPE_META;
|
|
6820
|
+
}
|
|
6821
|
+
/** Runtime-string-safe role lookup; unknown roles fall back to `GenericSensor`. */
|
|
6822
|
+
function deviceRoleMetaOf(role) {
|
|
6823
|
+
if (!isDeviceRole(role)) return FALLBACK_DEVICE_ROLE_META;
|
|
6824
|
+
return DEVICE_ROLE_META[role] ?? FALLBACK_DEVICE_ROLE_META;
|
|
6825
|
+
}
|
|
6826
|
+
/**
|
|
6827
|
+
* Icons an operator may pick for a per-device `display.icon` override (and for
|
|
6828
|
+
* a per-role default), keyed by a stable kebab-case name. Named imports only —
|
|
6829
|
+
* no dynamic indexing into lucide, so the bundle carries exactly this set.
|
|
6830
|
+
* Unknown keys resolve to `undefined` (caller falls through to the next level).
|
|
6478
6831
|
*
|
|
6479
|
-
*
|
|
6480
|
-
*
|
|
6481
|
-
*
|
|
6482
|
-
*
|
|
6483
|
-
*
|
|
6484
|
-
*
|
|
6832
|
+
* The vocabulary is the one the VIEWER draws from too (its own icon module,
|
|
6833
|
+
* keyed by these same strings): a key added here that the phone cannot draw
|
|
6834
|
+
* falls through to the next resolution level there, which reads as "my change
|
|
6835
|
+
* did nothing". So the KEY is the contract — a stable kebab-case string, never
|
|
6836
|
+
* a glyph identity — and `device-meta.test.ts` pins that every key resolves
|
|
6837
|
+
* and that the set never loses a key an operator may already have persisted.
|
|
6838
|
+
*
|
|
6839
|
+
* Grouped by what an operator is naming: a device, a light or appliance, a
|
|
6840
|
+
* sensor or the weather it reads, a room, or what moves through it. `gauge2`
|
|
6841
|
+
* is a legacy alias kept for rows that persisted it.
|
|
6485
6842
|
*/
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6843
|
+
var DISPLAY_ICON_REGISTRY = {
|
|
6844
|
+
camera: Camera,
|
|
6845
|
+
network: Network,
|
|
6846
|
+
"toggle-left": ToggleLeft,
|
|
6847
|
+
"toggle-right": ToggleRight,
|
|
6848
|
+
"circle-dot": CircleDot,
|
|
6849
|
+
"refresh-cw": RefreshCw,
|
|
6850
|
+
box: Box,
|
|
6851
|
+
"scroll-text": ScrollText,
|
|
6852
|
+
workflow: Workflow,
|
|
6853
|
+
lock: Lock,
|
|
6854
|
+
"lock-open": LockOpen,
|
|
6855
|
+
blinds: Blinds,
|
|
6856
|
+
"air-vent": AirVent,
|
|
6857
|
+
"monitor-play": MonitorPlay,
|
|
6858
|
+
"sliders-horizontal": SlidersHorizontal,
|
|
6859
|
+
"map-pin": MapPin,
|
|
6860
|
+
bot: Bot,
|
|
6861
|
+
tractor: Tractor,
|
|
6862
|
+
image: Image,
|
|
6863
|
+
bone: Bone,
|
|
6864
|
+
"door-closed": DoorClosed,
|
|
6865
|
+
"door-open": DoorOpen,
|
|
6866
|
+
crosshair: Crosshair,
|
|
6867
|
+
eye: Eye,
|
|
6868
|
+
"eye-off": EyeOff,
|
|
6869
|
+
smartphone: Smartphone,
|
|
6870
|
+
phone: Phone,
|
|
6871
|
+
tablet: Tablet,
|
|
6872
|
+
laptop: Laptop,
|
|
6873
|
+
monitor: Monitor,
|
|
6874
|
+
tv: Tv,
|
|
6875
|
+
speaker: Speaker,
|
|
6876
|
+
printer: Printer,
|
|
6877
|
+
projector: Projector,
|
|
6878
|
+
"gamepad-2": Gamepad2,
|
|
6879
|
+
radio: Radio,
|
|
6880
|
+
router: Router,
|
|
6881
|
+
bluetooth: Bluetooth,
|
|
6882
|
+
cpu: Cpu,
|
|
6883
|
+
"hard-drive": HardDrive,
|
|
6884
|
+
server: Server,
|
|
6885
|
+
mic: Mic,
|
|
6886
|
+
"mic-off": MicOff,
|
|
6887
|
+
video: Video,
|
|
6888
|
+
"video-off": VideoOff,
|
|
6889
|
+
music: Music,
|
|
6890
|
+
plug: Plug,
|
|
6891
|
+
"plug-zap": PlugZap,
|
|
6892
|
+
power: Power,
|
|
6893
|
+
"power-off": PowerOff,
|
|
6894
|
+
cable: Cable,
|
|
6895
|
+
battery: Battery,
|
|
6896
|
+
"battery-charging": BatteryCharging,
|
|
6897
|
+
"battery-full": BatteryFull,
|
|
6898
|
+
"battery-low": BatteryLow,
|
|
6899
|
+
key: Key,
|
|
6900
|
+
"key-round": KeyRound,
|
|
6901
|
+
mailbox: Mailbox,
|
|
6902
|
+
package: Package,
|
|
6903
|
+
shield: Shield,
|
|
6904
|
+
"shield-check": ShieldCheck,
|
|
6905
|
+
"shield-off": ShieldOff,
|
|
6906
|
+
lightbulb: Lightbulb,
|
|
6907
|
+
lamp: Lamp,
|
|
6908
|
+
"lamp-ceiling": LampCeiling,
|
|
6909
|
+
"lamp-desk": LampDesk,
|
|
6910
|
+
"lamp-floor": LampFloor,
|
|
6911
|
+
flashlight: Flashlight,
|
|
6912
|
+
heater: Heater,
|
|
6913
|
+
snowflake: Snowflake,
|
|
6914
|
+
"thermometer-sun": ThermometerSun,
|
|
6915
|
+
"thermometer-snowflake": ThermometerSnowflake,
|
|
6916
|
+
refrigerator: Refrigerator,
|
|
6917
|
+
microwave: Microwave,
|
|
6918
|
+
"washing-machine": WashingMachine,
|
|
6919
|
+
"cooking-pot": CookingPot,
|
|
6920
|
+
utensils: Utensils,
|
|
6921
|
+
thermometer: Thermometer,
|
|
6922
|
+
droplets: Droplets,
|
|
6923
|
+
droplet: Droplet,
|
|
6924
|
+
gauge: Gauge,
|
|
6925
|
+
gauge2: Gauge,
|
|
6926
|
+
sun: Sun,
|
|
6927
|
+
"sun-medium": SunMedium,
|
|
6928
|
+
sunrise: Sunrise,
|
|
6929
|
+
moon: Moon,
|
|
6930
|
+
wind: Wind,
|
|
6931
|
+
cloud: Cloud,
|
|
6932
|
+
"cloud-rain": CloudRain,
|
|
6933
|
+
"cloud-sun": CloudSun,
|
|
6934
|
+
waves: Waves,
|
|
6935
|
+
sprout: Sprout,
|
|
6936
|
+
leaf: Leaf,
|
|
6937
|
+
flower: Flower,
|
|
6938
|
+
zap: Zap,
|
|
6939
|
+
flame: Flame,
|
|
6940
|
+
bell: Bell,
|
|
6941
|
+
"bell-ring": BellRing,
|
|
6942
|
+
"bell-off": BellOff,
|
|
6943
|
+
siren: Siren,
|
|
6944
|
+
radar: Radar,
|
|
6945
|
+
activity: Activity,
|
|
6946
|
+
hash: Hash,
|
|
6947
|
+
clock: Clock,
|
|
6948
|
+
timer: Timer,
|
|
6949
|
+
calendar: Calendar,
|
|
6950
|
+
pipette: Pipette,
|
|
6951
|
+
fan: Fan,
|
|
6952
|
+
bath: Bath,
|
|
6953
|
+
footprints: Footprints,
|
|
6954
|
+
"alarm-smoke": AlarmSmoke,
|
|
6955
|
+
"shield-alert": ShieldAlert,
|
|
6956
|
+
vibrate: Vibrate,
|
|
6957
|
+
wifi: Wifi,
|
|
6958
|
+
"wifi-off": WifiOff,
|
|
6959
|
+
"volume-2": Volume2,
|
|
6960
|
+
"volume-x": VolumeX,
|
|
6961
|
+
heart: Heart,
|
|
6962
|
+
"heart-pulse": HeartPulse,
|
|
6963
|
+
star: Star,
|
|
6964
|
+
sparkles: Sparkles,
|
|
6965
|
+
house: House,
|
|
6966
|
+
sofa: Sofa,
|
|
6967
|
+
"bed-double": BedDouble,
|
|
6968
|
+
bed: Bed,
|
|
6969
|
+
warehouse: Warehouse,
|
|
6970
|
+
trees: Trees,
|
|
6971
|
+
"tree-pine": TreePine,
|
|
6972
|
+
fence: Fence,
|
|
6973
|
+
store: Store,
|
|
6974
|
+
building: Building,
|
|
6975
|
+
"building-2": Building2,
|
|
6976
|
+
mountain: Mountain,
|
|
6977
|
+
umbrella: Umbrella,
|
|
6978
|
+
dumbbell: Dumbbell,
|
|
6979
|
+
wrench: Wrench,
|
|
6980
|
+
hammer: Hammer,
|
|
6981
|
+
drill: Drill,
|
|
6982
|
+
"waves-ladder": WavesLadder,
|
|
6983
|
+
"circle-parking": CircleParking,
|
|
6984
|
+
briefcase: Briefcase,
|
|
6985
|
+
route: Route,
|
|
6986
|
+
car: Car,
|
|
6987
|
+
bike: Bike,
|
|
6988
|
+
bus: Bus,
|
|
6989
|
+
truck: Truck,
|
|
6990
|
+
plane: Plane,
|
|
6991
|
+
"train-front": TrainFront,
|
|
6992
|
+
sailboat: Sailboat,
|
|
6993
|
+
dog: Dog,
|
|
6994
|
+
cat: Cat,
|
|
6995
|
+
bird: Bird,
|
|
6996
|
+
"paw-print": PawPrint,
|
|
6997
|
+
baby: Baby,
|
|
6998
|
+
user: User,
|
|
6999
|
+
users: Users,
|
|
7000
|
+
"person-standing": PersonStanding
|
|
7001
|
+
};
|
|
7002
|
+
/** Resolve a `display.icon` name to a lucide component, or `undefined` when the
|
|
7003
|
+
* name is not in the curated `DISPLAY_ICON_REGISTRY`. */
|
|
7004
|
+
function resolveDisplayIcon(name) {
|
|
7005
|
+
return Object.hasOwn(DISPLAY_ICON_REGISTRY, name) ? DISPLAY_ICON_REGISTRY[name] : void 0;
|
|
7006
|
+
}
|
|
7007
|
+
/**
|
|
7008
|
+
* EXHAUSTIVE device-type filter options — one entry per `DeviceType` member,
|
|
7009
|
+
* derived from `DEVICE_TYPE_META` so the set is always complete and a newly
|
|
7010
|
+
* added `DeviceType` automatically appears in every type filter (Devices page,
|
|
7011
|
+
* adoption modal, …) without touching any consumer.
|
|
7012
|
+
*
|
|
7013
|
+
* The previous per-consumer logic built options from the types PRESENT in the
|
|
7014
|
+
* list (or a hand-maintained subset), so recently-added types (vacuum, lawn
|
|
7015
|
+
* mower, valve, humidifier, water heater, weather, image, …) were silently
|
|
7016
|
+
* missing from the dropdown. This is the single source of truth instead.
|
|
7017
|
+
*
|
|
7018
|
+
* `id` is the raw `DeviceType` string (matches the filtering predicate, which
|
|
7019
|
+
* compares against `device.type`); `label` + `icon` come from the meta map.
|
|
7020
|
+
* Ordered by `DeviceType` declaration order for a stable, intentional layout.
|
|
7021
|
+
*/
|
|
7022
|
+
var ALL_DEVICE_TYPE_FILTER_OPTIONS = Object.values(_camstack_types.DeviceType).map((type) => {
|
|
7023
|
+
const meta = deviceTypeMetaOf(type);
|
|
7024
|
+
return {
|
|
7025
|
+
id: type,
|
|
7026
|
+
label: meta.label,
|
|
7027
|
+
icon: meta.icon
|
|
7028
|
+
};
|
|
7029
|
+
});
|
|
7030
|
+
function allDeviceTypeFilterOptions() {
|
|
7031
|
+
return ALL_DEVICE_TYPE_FILTER_OPTIONS;
|
|
7032
|
+
}
|
|
7033
|
+
//#endregion
|
|
7034
|
+
//#region src/composites/icon-picker.tsx
|
|
7035
|
+
/**
|
|
7036
|
+
* icon-picker — the ONE control for choosing an icon, wherever admin-ui asks.
|
|
7037
|
+
*
|
|
7038
|
+
* There were two: a device one over `DISPLAY_ICON_REGISTRY` and a room one
|
|
7039
|
+
* over `LOCATION_ICON_IDS`, identical apart from the vocabulary they walked.
|
|
7040
|
+
* That was tolerable while the device set was 56 glyphs in a flat grid. It is
|
|
7041
|
+
* not at 157: a picker that only lets the operator HUNT is a picker they stop
|
|
7042
|
+
* using, and the two copies were already drifting — only one of them had an
|
|
7043
|
+
* i18n'd label.
|
|
7044
|
+
*
|
|
7045
|
+
* So the vocabulary, the grouping and the search all come from
|
|
7046
|
+
* `@camstack/types`' `display-icon-vocabulary`, which is the same module the
|
|
7047
|
+
* viewer's sheet searches. What is left here is the web half: a popover, a
|
|
7048
|
+
* grid, and a text field.
|
|
7049
|
+
*
|
|
7050
|
+
* ## What it does NOT own
|
|
7051
|
+
*
|
|
7052
|
+
* - **The glyphs.** `resolveGlyph` is a prop, because this package's table is
|
|
7053
|
+
* `lucide-react` and the viewer's is `lucide-react-native`. A key this build
|
|
7054
|
+
* cannot draw is SKIPPED rather than rendered as a hole — an empty tile
|
|
7055
|
+
* reads as a rendering bug, not as a missing choice.
|
|
7056
|
+
* - **The words.** Every string is a prop. This package has no i18n (one file
|
|
7057
|
+
* in it imports react-i18next, and that is the exception), and a control
|
|
7058
|
+
* that reached for a translation would force it on every consumer.
|
|
7059
|
+
* - **The write.** `onPick` is called and that is all; whether it is a form
|
|
7060
|
+
* value or an immediate mutation is the caller's business, as it already was
|
|
7061
|
+
* in both pickers this replaces.
|
|
7062
|
+
*
|
|
7063
|
+
* ## The clear tile is never filtered away
|
|
7064
|
+
*
|
|
7065
|
+
* The "inherit" / "no icon" choice sits above the sections and ignores the
|
|
7066
|
+
* search. A query that hid it would strand the operator on a glyph they picked
|
|
7067
|
+
* by accident with no way back to the default — the one action a picker must
|
|
7068
|
+
* always offer.
|
|
7069
|
+
*/
|
|
7070
|
+
function IconPicker({ value, onPick, resolveGlyph, fallbackGlyph, labels, only, extraWords, clearGlyph, labelFor, disabled = false }) {
|
|
7071
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
7072
|
+
const [query, setQuery] = (0, react$1.useState)("");
|
|
7073
|
+
const allowed = (0, react$1.useMemo)(() => only === void 0 ? null : new Set(only), [only]);
|
|
7074
|
+
const sections = (0, react$1.useMemo)(() => {
|
|
7075
|
+
const hits = (0, _camstack_types.searchDisplayIcons)(query, extraWords);
|
|
7076
|
+
const byGroup = /* @__PURE__ */ new Map();
|
|
7077
|
+
for (const hit of hits) {
|
|
7078
|
+
const { key, group } = hit.entry;
|
|
7079
|
+
if (allowed !== null && !allowed.has(key)) continue;
|
|
7080
|
+
if (resolveGlyph(key) === void 0) continue;
|
|
7081
|
+
const bucket = byGroup.get(group);
|
|
7082
|
+
if (bucket === void 0) byGroup.set(group, [key]);
|
|
7083
|
+
else bucket.push(key);
|
|
7084
|
+
}
|
|
7085
|
+
return _camstack_types.DISPLAY_ICON_GROUPS.flatMap((group) => {
|
|
7086
|
+
const keys = byGroup.get(group);
|
|
7087
|
+
return keys === void 0 || keys.length === 0 ? [] : [{
|
|
7088
|
+
group,
|
|
7089
|
+
keys
|
|
7090
|
+
}];
|
|
7091
|
+
});
|
|
7092
|
+
}, [
|
|
7093
|
+
query,
|
|
7094
|
+
extraWords,
|
|
7095
|
+
allowed,
|
|
7096
|
+
resolveGlyph
|
|
7097
|
+
]);
|
|
7098
|
+
const Current = (value === null ? void 0 : resolveGlyph(value)) ?? fallbackGlyph;
|
|
7099
|
+
const choose = async (next) => {
|
|
7100
|
+
setOpen(false);
|
|
7101
|
+
setQuery("");
|
|
7102
|
+
await onPick(next);
|
|
7103
|
+
};
|
|
7104
|
+
const Clear = clearGlyph ?? fallbackGlyph;
|
|
7105
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7106
|
+
className: "relative flex shrink-0 items-center gap-2",
|
|
7107
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7108
|
+
type: "button",
|
|
7109
|
+
disabled,
|
|
7110
|
+
onClick: () => setOpen((o) => !o),
|
|
7111
|
+
"aria-expanded": open,
|
|
7112
|
+
"aria-label": labels.trigger,
|
|
7113
|
+
title: labels.trigger,
|
|
7114
|
+
className: "rounded border border-border p-1 text-foreground-muted hover:bg-surface-hover disabled:opacity-50",
|
|
7115
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Current, { className: "h-4 w-4" })
|
|
7116
|
+
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7117
|
+
type: "button",
|
|
7118
|
+
"aria-label": labels.close,
|
|
7119
|
+
onClick: () => setOpen(false),
|
|
7120
|
+
className: "fixed inset-0 z-10 cursor-default"
|
|
7121
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7122
|
+
role: "group",
|
|
7123
|
+
"aria-label": labels.panel,
|
|
7124
|
+
className: "absolute left-0 top-full z-20 mt-1 max-h-80 w-72 overflow-y-auto rounded-md border border-border bg-surface p-2 shadow-lg",
|
|
7125
|
+
children: [
|
|
7126
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
7127
|
+
type: "search",
|
|
7128
|
+
value: query,
|
|
7129
|
+
autoFocus: true,
|
|
7130
|
+
onChange: (e) => setQuery(e.target.value),
|
|
7131
|
+
placeholder: labels.searchPlaceholder,
|
|
7132
|
+
"aria-label": labels.searchPlaceholder,
|
|
7133
|
+
className: "mb-2 w-full rounded border border-border bg-surface-raised px-2 py-1 text-xs text-foreground placeholder:text-foreground-subtle"
|
|
7134
|
+
}),
|
|
7135
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7136
|
+
type: "button",
|
|
7137
|
+
onClick: () => void choose(null),
|
|
7138
|
+
"aria-pressed": value === null,
|
|
7139
|
+
className: "mb-2 flex w-full items-center gap-1.5 rounded px-1.5 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover",
|
|
7140
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Clear, { className: "h-3.5 w-3.5" }), labels.clear]
|
|
7141
|
+
}),
|
|
7142
|
+
sections.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7143
|
+
className: "px-1.5 py-2 text-[11px] text-foreground-subtle",
|
|
7144
|
+
children: labels.noMatches
|
|
7145
|
+
}) : sections.map(({ group, keys }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
7146
|
+
className: "mb-2 last:mb-0",
|
|
7147
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
7148
|
+
className: "px-1.5 pb-1 text-[10px] uppercase tracking-wide text-foreground-subtle",
|
|
7149
|
+
children: labels.groups[group]
|
|
7150
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7151
|
+
className: "grid grid-cols-7 gap-1",
|
|
7152
|
+
children: keys.map((key) => {
|
|
7153
|
+
const Glyph = resolveGlyph(key);
|
|
7154
|
+
if (Glyph === void 0) return null;
|
|
7155
|
+
const selected = value === key;
|
|
7156
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7157
|
+
type: "button",
|
|
7158
|
+
onClick: () => void choose(key),
|
|
7159
|
+
"aria-pressed": selected,
|
|
7160
|
+
"aria-label": labelFor?.(key) ?? key,
|
|
7161
|
+
title: labelFor?.(key) ?? key,
|
|
7162
|
+
className: selected ? "flex items-center justify-center rounded border border-primary bg-primary/10 p-1.5 text-foreground" : "flex items-center justify-center rounded border border-transparent p-1.5 text-foreground-muted hover:bg-surface-hover",
|
|
7163
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Glyph, { className: "h-4 w-4" })
|
|
7164
|
+
}, key);
|
|
7165
|
+
})
|
|
7166
|
+
})]
|
|
7167
|
+
}, group))
|
|
7168
|
+
]
|
|
7169
|
+
})] })]
|
|
7170
|
+
});
|
|
7171
|
+
}
|
|
7172
|
+
//#endregion
|
|
7173
|
+
//#region src/composites/config-icon-field.tsx
|
|
7174
|
+
/**
|
|
7175
|
+
* The control behind a `type: 'icon'` settings field (D780).
|
|
7176
|
+
*
|
|
7177
|
+
* The shared `<IconPicker>` over the display-icon vocabulary, with the device
|
|
7178
|
+
* glyph table — the same control and the same keys the device and room
|
|
7179
|
+
* pickers use. An icon field always draws something, so clearing is "back to
|
|
7180
|
+
* the field's default", and a stored value the vocabulary does not know (a
|
|
7181
|
+
* free-text lucide name from before D780) is drawn as that default.
|
|
7182
|
+
*/
|
|
7183
|
+
function labelsFor(label) {
|
|
7184
|
+
return {
|
|
7185
|
+
trigger: `Choose an icon for ${label}`,
|
|
7186
|
+
panel: `${label} icon`,
|
|
7187
|
+
close: "Close",
|
|
7188
|
+
searchPlaceholder: "Search icons",
|
|
7189
|
+
clear: "Default icon",
|
|
7190
|
+
noMatches: "No icon matches",
|
|
7191
|
+
groups: {
|
|
7192
|
+
device: "Devices",
|
|
7193
|
+
lighting: "Lighting",
|
|
7194
|
+
sensing: "Sensing",
|
|
7195
|
+
place: "Places",
|
|
7196
|
+
life: "Life"
|
|
7197
|
+
}
|
|
7198
|
+
};
|
|
7199
|
+
}
|
|
7200
|
+
function ConfigIconFieldControl({ label, value, defaultKey, disabled, onChange }) {
|
|
7201
|
+
const key = (0, _camstack_types.resolveDisplayIconKey)(value, defaultKey);
|
|
7202
|
+
const DefaultGlyph = resolveDisplayIcon(defaultKey) ?? ShieldCheck;
|
|
7203
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7204
|
+
className: "flex items-center gap-2",
|
|
7205
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconPicker, {
|
|
7206
|
+
value: key === "" ? null : key,
|
|
7207
|
+
onPick: (next) => onChange(next ?? defaultKey),
|
|
7208
|
+
resolveGlyph: resolveDisplayIcon,
|
|
7209
|
+
fallbackGlyph: DefaultGlyph,
|
|
7210
|
+
labels: labelsFor(label),
|
|
7211
|
+
disabled
|
|
7212
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7213
|
+
className: "text-[11px] text-foreground-subtle font-mono",
|
|
7214
|
+
children: key
|
|
7215
|
+
})]
|
|
7216
|
+
});
|
|
7217
|
+
}
|
|
7218
|
+
//#endregion
|
|
7219
|
+
//#region src/generated/system-hooks.ts
|
|
7220
|
+
/**
|
|
7221
|
+
* Per-method React-Query hooks for every `scope: 'system'` capability.
|
|
7222
|
+
*
|
|
7223
|
+
* Each hook is a thin pass-through to `trpc.<cap>.<method>.useQuery` /
|
|
7224
|
+
* `.useMutation` / `.useSubscription` so the typed inference + RQ
|
|
7225
|
+
* cache/dedup keep working — the generator only contributes a consistent
|
|
7226
|
+
* name and stable export surface so admin-ui pages can write
|
|
7227
|
+
* `useAddonsList()` instead of `trpc.addons.list.useQuery()`.
|
|
7228
|
+
*
|
|
7229
|
+
* Push-subscription methods (`kind: 'subscription'`) emit a typeof
|
|
7230
|
+
* alias over `useSubscription`, so the call shape is
|
|
7231
|
+
* `useToastOnToast(input, { onData: cb })` — same as the underlying
|
|
7232
|
+
* tRPC hook. The eventBus-backed `useLiveEvent` (see
|
|
7233
|
+
* `../hooks/use-live-event.ts`) covers events that don't ride a tRPC
|
|
7234
|
+
* subscription; the two surfaces coexist by design.
|
|
7235
|
+
*/
|
|
7236
|
+
/** Generated alias around `trpc.accessories.setChildHidden.useMutation`. */
|
|
7237
|
+
var useAccessoriesSetChildHidden = trpc.accessories.setChildHidden.useMutation;
|
|
7238
|
+
/** Generated alias around `trpc.accessories.getStatus.useQuery`. */
|
|
7239
|
+
var useAccessoriesGetStatus = trpc.accessories.getStatus.useQuery;
|
|
7240
|
+
/** Generated alias around `trpc.addonPages.listPages.useQuery`. */
|
|
7241
|
+
var useAddonPagesListPages = trpc.addonPages.listPages.useQuery;
|
|
7242
|
+
/** Generated alias around `trpc.addons.list.useQuery`. */
|
|
7243
|
+
var useAddonsList = trpc.addons.list.useQuery;
|
|
7244
|
+
/** Generated alias around `trpc.addons.getLogs.useQuery`. */
|
|
7245
|
+
var useAddonsGetLogs = trpc.addons.getLogs.useQuery;
|
|
7246
|
+
/** Generated alias around `trpc.addons.listPackages.useQuery`. */
|
|
7247
|
+
var useAddonsListPackages = trpc.addons.listPackages.useQuery;
|
|
7248
|
+
/** Generated alias around `trpc.addons.installPackage.useMutation`. */
|
|
7249
|
+
var useAddonsInstallPackage = trpc.addons.installPackage.useMutation;
|
|
7250
|
+
/** Generated alias around `trpc.addons.installFromWorkspace.useMutation`. */
|
|
7251
|
+
var useAddonsInstallFromWorkspace = trpc.addons.installFromWorkspace.useMutation;
|
|
7252
|
+
/** Generated alias around `trpc.addons.isWorkspaceAvailable.useQuery`. */
|
|
7253
|
+
var useAddonsIsWorkspaceAvailable = trpc.addons.isWorkspaceAvailable.useQuery;
|
|
7254
|
+
/** Generated alias around `trpc.addons.listWorkspacePackages.useQuery`. */
|
|
7255
|
+
var useAddonsListWorkspacePackages = trpc.addons.listWorkspacePackages.useQuery;
|
|
7256
|
+
/** Generated alias around `trpc.addons.uninstallPackage.useMutation`. */
|
|
7257
|
+
var useAddonsUninstallPackage = trpc.addons.uninstallPackage.useMutation;
|
|
7258
|
+
/** Generated alias around `trpc.addons.listInstallations.useQuery`. */
|
|
7259
|
+
var useAddonsListInstallations = trpc.addons.listInstallations.useQuery;
|
|
7260
|
+
/** Generated alias around `trpc.addons.reloadPackages.useMutation`. */
|
|
7261
|
+
var useAddonsReloadPackages = trpc.addons.reloadPackages.useMutation;
|
|
7262
|
+
/** Generated alias around `trpc.addons.searchAvailable.useQuery`. */
|
|
7263
|
+
var useAddonsSearchAvailable = trpc.addons.searchAvailable.useQuery;
|
|
7264
|
+
/** Generated alias around `trpc.addons.listUpdates.useQuery`. */
|
|
7265
|
+
var useAddonsListUpdates = trpc.addons.listUpdates.useQuery;
|
|
7266
|
+
/** Generated alias around `trpc.addons.updatePackage.useMutation`. */
|
|
7267
|
+
var useAddonsUpdatePackage = trpc.addons.updatePackage.useMutation;
|
|
7268
|
+
/** Generated alias around `trpc.addons.rollbackPackage.useMutation`. */
|
|
7269
|
+
var useAddonsRollbackPackage = trpc.addons.rollbackPackage.useMutation;
|
|
7270
|
+
/** Generated alias around `trpc.addons.forceRefresh.useMutation`. */
|
|
7271
|
+
var useAddonsForceRefresh = trpc.addons.forceRefresh.useMutation;
|
|
7272
|
+
/** Generated alias around `trpc.addons.restartServer.useMutation`. */
|
|
7273
|
+
var useAddonsRestartServer = trpc.addons.restartServer.useMutation;
|
|
7274
|
+
/** Generated alias around `trpc.addons.getLastRestart.useQuery`. */
|
|
7275
|
+
var useAddonsGetLastRestart = trpc.addons.getLastRestart.useQuery;
|
|
7276
|
+
/** Generated alias around `trpc.addons.listFrameworkPackages.useQuery`. */
|
|
7277
|
+
var useAddonsListFrameworkPackages = trpc.addons.listFrameworkPackages.useQuery;
|
|
7278
|
+
/** Generated alias around `trpc.addons.listCapabilityProviders.useQuery`. */
|
|
7279
|
+
var useAddonsListCapabilityProviders = trpc.addons.listCapabilityProviders.useQuery;
|
|
7280
|
+
/** Generated alias around `trpc.addons.setCapabilityProviderEnabled.useMutation`. */
|
|
7281
|
+
var useAddonsSetCapabilityProviderEnabled = trpc.addons.setCapabilityProviderEnabled.useMutation;
|
|
7282
|
+
/** Generated alias around `trpc.addons.getVersions.useQuery`. */
|
|
7283
|
+
var useAddonsGetVersions = trpc.addons.getVersions.useQuery;
|
|
7284
|
+
/** Generated alias around `trpc.addons.restartAddon.useMutation`. */
|
|
7285
|
+
var useAddonsRestartAddon = trpc.addons.restartAddon.useMutation;
|
|
7286
|
+
/** Generated alias around `trpc.addons.retryLoad.useMutation`. */
|
|
7287
|
+
var useAddonsRetryLoad = trpc.addons.retryLoad.useMutation;
|
|
7288
|
+
/** Generated alias around `trpc.addons.getAutoUpdateSettings.useQuery`. */
|
|
7289
|
+
var useAddonsGetAutoUpdateSettings = trpc.addons.getAutoUpdateSettings.useQuery;
|
|
7290
|
+
/** Generated alias around `trpc.addons.setAutoUpdateSettings.useMutation`. */
|
|
7291
|
+
var useAddonsSetAutoUpdateSettings = trpc.addons.setAutoUpdateSettings.useMutation;
|
|
7292
|
+
/** Generated alias around `trpc.addons.getAddonAutoUpdate.useQuery`. */
|
|
7293
|
+
var useAddonsGetAddonAutoUpdate = trpc.addons.getAddonAutoUpdate.useQuery;
|
|
7294
|
+
/** Generated alias around `trpc.addons.setAddonAutoUpdate.useMutation`. */
|
|
7295
|
+
var useAddonsSetAddonAutoUpdate = trpc.addons.setAddonAutoUpdate.useMutation;
|
|
7296
|
+
/** Generated alias around `trpc.addons.applyAutoUpdateToAll.useMutation`. */
|
|
7297
|
+
var useAddonsApplyAutoUpdateToAll = trpc.addons.applyAutoUpdateToAll.useMutation;
|
|
7298
|
+
/** Generated alias around `trpc.addons.custom.useMutation`. */
|
|
7299
|
+
var useAddonsCustom = trpc.addons.custom.useMutation;
|
|
7300
|
+
/** Generated alias around `trpc.addons.startJob.useMutation`. */
|
|
7301
|
+
var useAddonsStartJob = trpc.addons.startJob.useMutation;
|
|
7302
|
+
/** Generated alias around `trpc.addons.getJob.useQuery`. */
|
|
7303
|
+
var useAddonsGetJob = trpc.addons.getJob.useQuery;
|
|
7304
|
+
/** Generated alias around `trpc.addons.listJobs.useQuery`. */
|
|
7305
|
+
var useAddonsListJobs = trpc.addons.listJobs.useQuery;
|
|
7306
|
+
/** Generated alias around `trpc.addons.cancelJob.useMutation`. */
|
|
7307
|
+
var useAddonsCancelJob = trpc.addons.cancelJob.useMutation;
|
|
7308
|
+
/** Generated alias around `trpc.addons.onAddonLogs.useSubscription`. */
|
|
7309
|
+
var useAddonsOnAddonLogs = trpc.addons.onAddonLogs.useSubscription;
|
|
7310
|
+
/** Generated alias around `trpc.addonSettings.getGlobalSettings.useQuery`. */
|
|
7311
|
+
var useAddonSettingsGetGlobalSettings = trpc.addonSettings.getGlobalSettings.useQuery;
|
|
7312
|
+
/** Generated alias around `trpc.addonSettings.updateGlobalSettings.useMutation`. */
|
|
7313
|
+
var useAddonSettingsUpdateGlobalSettings = trpc.addonSettings.updateGlobalSettings.useMutation;
|
|
7314
|
+
/** Generated alias around `trpc.addonSettings.getIntegrationSettings.useQuery`. */
|
|
7315
|
+
var useAddonSettingsGetIntegrationSettings = trpc.addonSettings.getIntegrationSettings.useQuery;
|
|
7316
|
+
/** Generated alias around `trpc.addonSettings.getDeviceSettings.useQuery`. */
|
|
7317
|
+
var useAddonSettingsGetDeviceSettings = trpc.addonSettings.getDeviceSettings.useQuery;
|
|
7318
|
+
/** Generated alias around `trpc.addonSettings.updateDeviceSettings.useMutation`. */
|
|
7319
|
+
var useAddonSettingsUpdateDeviceSettings = trpc.addonSettings.updateDeviceSettings.useMutation;
|
|
7320
|
+
/** Generated alias around `trpc.addonWidgets.listWidgets.useQuery`. */
|
|
7321
|
+
var useAddonWidgetsListWidgets = trpc.addonWidgets.listWidgets.useQuery;
|
|
7322
|
+
/** Generated alias around `trpc.airQualitySensor.getStatus.useQuery`. */
|
|
7323
|
+
var useAirQualitySensorGetStatus = trpc.airQualitySensor.getStatus.useQuery;
|
|
7324
|
+
/** Generated alias around `trpc.alarmPanel.arm.useMutation`. */
|
|
7325
|
+
var useAlarmPanelArm = trpc.alarmPanel.arm.useMutation;
|
|
7326
|
+
/** Generated alias around `trpc.alarmPanel.disarm.useMutation`. */
|
|
7327
|
+
var useAlarmPanelDisarm = trpc.alarmPanel.disarm.useMutation;
|
|
7328
|
+
/** Generated alias around `trpc.alarmPanel.trigger.useMutation`. */
|
|
7329
|
+
var useAlarmPanelTrigger = trpc.alarmPanel.trigger.useMutation;
|
|
7330
|
+
/** Generated alias around `trpc.alarmPanel.getStatus.useQuery`. */
|
|
7331
|
+
var useAlarmPanelGetStatus = trpc.alarmPanel.getStatus.useQuery;
|
|
7332
|
+
/** Generated alias around `trpc.alerts.emit.useMutation`. */
|
|
7333
|
+
var useAlertsEmit = trpc.alerts.emit.useMutation;
|
|
7334
|
+
/** Generated alias around `trpc.alerts.update.useMutation`. */
|
|
7335
|
+
var useAlertsUpdate = trpc.alerts.update.useMutation;
|
|
7336
|
+
/** Generated alias around `trpc.alerts.list.useQuery`. */
|
|
7337
|
+
var useAlertsList = trpc.alerts.list.useQuery;
|
|
7338
|
+
/** Generated alias around `trpc.alerts.getUnreadCount.useQuery`. */
|
|
7339
|
+
var useAlertsGetUnreadCount = trpc.alerts.getUnreadCount.useQuery;
|
|
7340
|
+
/** Generated alias around `trpc.alerts.markRead.useMutation`. */
|
|
7341
|
+
var useAlertsMarkRead = trpc.alerts.markRead.useMutation;
|
|
7342
|
+
/** Generated alias around `trpc.alerts.markAllRead.useMutation`. */
|
|
7343
|
+
var useAlertsMarkAllRead = trpc.alerts.markAllRead.useMutation;
|
|
7344
|
+
/** Generated alias around `trpc.alerts.dismiss.useMutation`. */
|
|
7345
|
+
var useAlertsDismiss = trpc.alerts.dismiss.useMutation;
|
|
7346
|
+
/** Generated alias around `trpc.ambientLightSensor.getStatus.useQuery`. */
|
|
7347
|
+
var useAmbientLightSensorGetStatus = trpc.ambientLightSensor.getStatus.useQuery;
|
|
7348
|
+
/** Generated alias around `trpc.audioAnalysis.resolveDeviceSettings.useQuery`. */
|
|
7349
|
+
var useAudioAnalysisResolveDeviceSettings = trpc.audioAnalysis.resolveDeviceSettings.useQuery;
|
|
7350
|
+
/** Generated alias around `trpc.audioAnalysis.getDeviceSettingsContribution.useQuery`. */
|
|
7351
|
+
var useAudioAnalysisGetDeviceSettingsContribution = trpc.audioAnalysis.getDeviceSettingsContribution.useQuery;
|
|
7352
|
+
/** Generated alias around `trpc.audioAnalysis.getDeviceLiveContribution.useQuery`. */
|
|
7353
|
+
var useAudioAnalysisGetDeviceLiveContribution = trpc.audioAnalysis.getDeviceLiveContribution.useQuery;
|
|
7354
|
+
/** Generated alias around `trpc.audioAnalysis.applyDeviceSettingsPatch.useMutation`. */
|
|
7355
|
+
var useAudioAnalysisApplyDeviceSettingsPatch = trpc.audioAnalysis.applyDeviceSettingsPatch.useMutation;
|
|
7356
|
+
/** Generated alias around `trpc.audioAnalyzer.analyseChunk.useMutation`. */
|
|
7357
|
+
var useAudioAnalyzerAnalyseChunk = trpc.audioAnalyzer.analyseChunk.useMutation;
|
|
7358
|
+
/** Generated alias around `trpc.audioAnalyzer.classify.useQuery`. */
|
|
7359
|
+
var useAudioAnalyzerClassify = trpc.audioAnalyzer.classify.useQuery;
|
|
7360
|
+
/** Generated alias around `trpc.audioAnalyzer.attachDevice.useMutation`. */
|
|
7361
|
+
var useAudioAnalyzerAttachDevice = trpc.audioAnalyzer.attachDevice.useMutation;
|
|
7362
|
+
/** Generated alias around `trpc.audioAnalyzer.detachDevice.useMutation`. */
|
|
7363
|
+
var useAudioAnalyzerDetachDevice = trpc.audioAnalyzer.detachDevice.useMutation;
|
|
6614
7364
|
/** Generated alias around `trpc.audioAnalyzer.isReady.useQuery`. */
|
|
6615
7365
|
var useAudioAnalyzerIsReady = trpc.audioAnalyzer.isReady.useQuery;
|
|
6616
7366
|
/** Generated alias around `trpc.audioAnalyzer.dispose.useMutation`. */
|
|
@@ -7803,6 +8553,10 @@ var usePipelineAnalyticsCompleteRetrainTrack = trpc.pipelineAnalytics.completeRe
|
|
|
7803
8553
|
var usePipelineAnalyticsRestageRetrainTrack = trpc.pipelineAnalytics.restageRetrainTrack.useMutation;
|
|
7804
8554
|
/** Generated alias around `trpc.pipelineAnalytics.getRetrainExportUrl.useQuery`. */
|
|
7805
8555
|
var usePipelineAnalyticsGetRetrainExportUrl = trpc.pipelineAnalytics.getRetrainExportUrl.useQuery;
|
|
8556
|
+
/** Generated alias around `trpc.pipelineAnalytics.setRetrainFrameComplete.useMutation`. */
|
|
8557
|
+
var usePipelineAnalyticsSetRetrainFrameComplete = trpc.pipelineAnalytics.setRetrainFrameComplete.useMutation;
|
|
8558
|
+
/** Generated alias around `trpc.pipelineAnalytics.writeRetrainArchive.useMutation`. */
|
|
8559
|
+
var usePipelineAnalyticsWriteRetrainArchive = trpc.pipelineAnalytics.writeRetrainArchive.useMutation;
|
|
7806
8560
|
/** Generated alias around `trpc.pipelineAnalytics.getEventMedia.useQuery`. */
|
|
7807
8561
|
var usePipelineAnalyticsGetEventMedia = trpc.pipelineAnalytics.getEventMedia.useQuery;
|
|
7808
8562
|
/** Generated alias around `trpc.pipelineAnalytics.getTrackMedia.useQuery`. */
|
|
@@ -8591,6 +9345,14 @@ var useUserManagementOauthExchangeCode = trpc.userManagement.oauthExchangeCode.u
|
|
|
8591
9345
|
var useUserManagementOauthRefresh = trpc.userManagement.oauthRefresh.useMutation;
|
|
8592
9346
|
/** Generated alias around `trpc.userManagement.oauthVerifyAccessToken.useQuery`. */
|
|
8593
9347
|
var useUserManagementOauthVerifyAccessToken = trpc.userManagement.oauthVerifyAccessToken.useQuery;
|
|
9348
|
+
/** Generated alias around `trpc.userManagement.listExternalIdentities.useQuery`. */
|
|
9349
|
+
var useUserManagementListExternalIdentities = trpc.userManagement.listExternalIdentities.useQuery;
|
|
9350
|
+
/** Generated alias around `trpc.userManagement.findUserByExternalIdentity.useQuery`. */
|
|
9351
|
+
var useUserManagementFindUserByExternalIdentity = trpc.userManagement.findUserByExternalIdentity.useQuery;
|
|
9352
|
+
/** Generated alias around `trpc.userManagement.linkExternalIdentity.useMutation`. */
|
|
9353
|
+
var useUserManagementLinkExternalIdentity = trpc.userManagement.linkExternalIdentity.useMutation;
|
|
9354
|
+
/** Generated alias around `trpc.userManagement.unlinkExternalIdentity.useMutation`. */
|
|
9355
|
+
var useUserManagementUnlinkExternalIdentity = trpc.userManagement.unlinkExternalIdentity.useMutation;
|
|
8594
9356
|
/** Generated alias around `trpc.userManagement.listOauthSessions.useQuery`. */
|
|
8595
9357
|
var useUserManagementListOauthSessions = trpc.userManagement.listOauthSessions.useQuery;
|
|
8596
9358
|
/** Generated alias around `trpc.userManagement.revokeOauthSession.useMutation`. */
|
|
@@ -27166,6 +27928,23 @@ function ColorField({ field, value, onChange, disabled, translationFn }) {
|
|
|
27166
27928
|
})]
|
|
27167
27929
|
});
|
|
27168
27930
|
}
|
|
27931
|
+
function IconField({ field, value, onChange, disabled, translationFn }) {
|
|
27932
|
+
const defaultKey = typeof field.default === "string" ? field.default : "";
|
|
27933
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldWrapper, {
|
|
27934
|
+
label: field.label,
|
|
27935
|
+
description: field.description,
|
|
27936
|
+
required: field.required,
|
|
27937
|
+
span: field.span,
|
|
27938
|
+
translationFn,
|
|
27939
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigIconFieldControl, {
|
|
27940
|
+
label: resolveLabel(field.label, translationFn) ?? field.label,
|
|
27941
|
+
value,
|
|
27942
|
+
defaultKey,
|
|
27943
|
+
disabled: disabled || field.disabled,
|
|
27944
|
+
onChange
|
|
27945
|
+
})
|
|
27946
|
+
});
|
|
27947
|
+
}
|
|
27169
27948
|
function ProbeField({ field, value, onChange, disabled, translationFn, onTestField, onAction, externalProbe }) {
|
|
27170
27949
|
const [localStatus, setLocalStatus] = (0, react$1.useState)("idle");
|
|
27171
27950
|
const [localResult, setLocalResult] = (0, react$1.useState)(null);
|
|
@@ -27800,8 +28579,16 @@ function AddonActionButtonField({ field, values, disabled, onAction }) {
|
|
|
27800
28579
|
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
27801
28580
|
const [status, setStatus] = (0, react$1.useState)(null);
|
|
27802
28581
|
const confirm = useConfirm();
|
|
28582
|
+
const prompt = usePrompt();
|
|
27803
28583
|
const deviceId = useDeviceId();
|
|
27804
28584
|
const handleClick = async () => {
|
|
28585
|
+
const asked = field.prompt ? await prompt({
|
|
28586
|
+
title: field.prompt.title ?? field.label,
|
|
28587
|
+
...field.prompt.message !== void 0 ? { message: field.prompt.message } : {},
|
|
28588
|
+
...field.prompt.placeholder !== void 0 ? { placeholder: field.prompt.placeholder } : {},
|
|
28589
|
+
confirmLabel: field.buttonLabel
|
|
28590
|
+
}) : null;
|
|
28591
|
+
if (field.prompt && asked === null) return;
|
|
27805
28592
|
if (field.confirmMessage) {
|
|
27806
28593
|
if (!await confirm({
|
|
27807
28594
|
title: field.label,
|
|
@@ -27812,6 +28599,7 @@ function AddonActionButtonField({ field, values, disabled, onAction }) {
|
|
|
27812
28599
|
}
|
|
27813
28600
|
if (!onAction) return;
|
|
27814
28601
|
const params = resolveActionParams(field, values);
|
|
28602
|
+
if (field.prompt && asked !== null) params[field.prompt.param] = asked;
|
|
27815
28603
|
if (field.includeDeviceId === true && deviceId !== null && deviceId !== void 0) params["deviceId"] = deviceId;
|
|
27816
28604
|
setLoading(true);
|
|
27817
28605
|
setStatus(null);
|
|
@@ -28272,6 +29060,13 @@ function FormField({ field, values, onChange, disabled, translationFn, onTestFie
|
|
|
28272
29060
|
disabled,
|
|
28273
29061
|
translationFn
|
|
28274
29062
|
});
|
|
29063
|
+
case "icon": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconField, {
|
|
29064
|
+
field,
|
|
29065
|
+
value,
|
|
29066
|
+
onChange: handleChange,
|
|
29067
|
+
disabled,
|
|
29068
|
+
translationFn
|
|
29069
|
+
});
|
|
28275
29070
|
case "node-select": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectField, {
|
|
28276
29071
|
field,
|
|
28277
29072
|
value,
|
|
@@ -49746,7 +50541,7 @@ var CONTROL_FILLS = {
|
|
|
49746
50541
|
[_camstack_types.DeviceType.Image]: false,
|
|
49747
50542
|
[_camstack_types.DeviceType.PetFeeder]: false
|
|
49748
50543
|
};
|
|
49749
|
-
var DEVICE_TYPE_VALUES
|
|
50544
|
+
var DEVICE_TYPE_VALUES = new Set(Object.values(_camstack_types.DeviceType));
|
|
49750
50545
|
/**
|
|
49751
50546
|
* Runtime-string-safe lookup: a device row's `type` crosses the wire as a plain
|
|
49752
50547
|
* string. The type→control-kind DECISION is single-sourced in `@camstack/types`
|
|
@@ -49772,7 +50567,7 @@ function resolveDeviceControl(type) {
|
|
|
49772
50567
|
*/
|
|
49773
50568
|
function resolveControlAlign(type, placement) {
|
|
49774
50569
|
if (placement === "table") return "fit";
|
|
49775
|
-
return DEVICE_TYPE_VALUES
|
|
50570
|
+
return DEVICE_TYPE_VALUES.has(type) && CONTROL_FILLS[type] ? FILL : placement === "center" ? CENTER : RIGHT;
|
|
49776
50571
|
}
|
|
49777
50572
|
//#endregion
|
|
49778
50573
|
//#region src/lib/format-last-seen.ts
|
|
@@ -50100,571 +50895,6 @@ function DeviceBatchActionsBar(props) {
|
|
|
50100
50895
|
})] });
|
|
50101
50896
|
}
|
|
50102
50897
|
//#endregion
|
|
50103
|
-
//#region src/composites/device-meta.ts
|
|
50104
|
-
var DEVICE_TYPE_META = {
|
|
50105
|
-
[_camstack_types.DeviceType.Camera]: {
|
|
50106
|
-
icon: Camera,
|
|
50107
|
-
label: "Camera"
|
|
50108
|
-
},
|
|
50109
|
-
[_camstack_types.DeviceType.Hub]: {
|
|
50110
|
-
icon: Network,
|
|
50111
|
-
label: "Hub"
|
|
50112
|
-
},
|
|
50113
|
-
[_camstack_types.DeviceType.Light]: {
|
|
50114
|
-
icon: Lightbulb,
|
|
50115
|
-
label: "Light"
|
|
50116
|
-
},
|
|
50117
|
-
[_camstack_types.DeviceType.Siren]: {
|
|
50118
|
-
icon: Siren,
|
|
50119
|
-
label: "Siren"
|
|
50120
|
-
},
|
|
50121
|
-
[_camstack_types.DeviceType.Switch]: {
|
|
50122
|
-
icon: ToggleLeft,
|
|
50123
|
-
label: "Switch"
|
|
50124
|
-
},
|
|
50125
|
-
[_camstack_types.DeviceType.Sensor]: {
|
|
50126
|
-
icon: Activity,
|
|
50127
|
-
label: "Sensor"
|
|
50128
|
-
},
|
|
50129
|
-
[_camstack_types.DeviceType.Thermostat]: {
|
|
50130
|
-
icon: Thermometer,
|
|
50131
|
-
label: "Thermostat"
|
|
50132
|
-
},
|
|
50133
|
-
[_camstack_types.DeviceType.Climate]: {
|
|
50134
|
-
icon: AirVent,
|
|
50135
|
-
label: "Air conditioner"
|
|
50136
|
-
},
|
|
50137
|
-
[_camstack_types.DeviceType.Button]: {
|
|
50138
|
-
icon: CircleDot,
|
|
50139
|
-
label: "Button"
|
|
50140
|
-
},
|
|
50141
|
-
[_camstack_types.DeviceType.EventEmitter]: {
|
|
50142
|
-
icon: Zap,
|
|
50143
|
-
label: "Event Emitter"
|
|
50144
|
-
},
|
|
50145
|
-
[_camstack_types.DeviceType.Update]: {
|
|
50146
|
-
icon: RefreshCw,
|
|
50147
|
-
label: "Update"
|
|
50148
|
-
},
|
|
50149
|
-
[_camstack_types.DeviceType.Generic]: {
|
|
50150
|
-
icon: Box,
|
|
50151
|
-
label: "Generic"
|
|
50152
|
-
},
|
|
50153
|
-
[_camstack_types.DeviceType.Notifier]: {
|
|
50154
|
-
icon: Bell,
|
|
50155
|
-
label: "Notifier"
|
|
50156
|
-
},
|
|
50157
|
-
[_camstack_types.DeviceType.Script]: {
|
|
50158
|
-
icon: ScrollText,
|
|
50159
|
-
label: "Script"
|
|
50160
|
-
},
|
|
50161
|
-
[_camstack_types.DeviceType.Automation]: {
|
|
50162
|
-
icon: Workflow,
|
|
50163
|
-
label: "Automation"
|
|
50164
|
-
},
|
|
50165
|
-
[_camstack_types.DeviceType.Lock]: {
|
|
50166
|
-
icon: Lock,
|
|
50167
|
-
label: "Lock"
|
|
50168
|
-
},
|
|
50169
|
-
[_camstack_types.DeviceType.Cover]: {
|
|
50170
|
-
icon: Blinds,
|
|
50171
|
-
label: "Cover"
|
|
50172
|
-
},
|
|
50173
|
-
[_camstack_types.DeviceType.Valve]: {
|
|
50174
|
-
icon: Pipette,
|
|
50175
|
-
label: "Valve"
|
|
50176
|
-
},
|
|
50177
|
-
[_camstack_types.DeviceType.Humidifier]: {
|
|
50178
|
-
icon: Waves,
|
|
50179
|
-
label: "Humidifier"
|
|
50180
|
-
},
|
|
50181
|
-
[_camstack_types.DeviceType.WaterHeater]: {
|
|
50182
|
-
icon: Bath,
|
|
50183
|
-
label: "Water heater"
|
|
50184
|
-
},
|
|
50185
|
-
[_camstack_types.DeviceType.Fan]: {
|
|
50186
|
-
icon: Fan,
|
|
50187
|
-
label: "Fan"
|
|
50188
|
-
},
|
|
50189
|
-
[_camstack_types.DeviceType.MediaPlayer]: {
|
|
50190
|
-
icon: MonitorPlay,
|
|
50191
|
-
label: "Media player"
|
|
50192
|
-
},
|
|
50193
|
-
[_camstack_types.DeviceType.AlarmPanel]: {
|
|
50194
|
-
icon: ShieldAlert,
|
|
50195
|
-
label: "Alarm panel"
|
|
50196
|
-
},
|
|
50197
|
-
[_camstack_types.DeviceType.Control]: {
|
|
50198
|
-
icon: SlidersHorizontal,
|
|
50199
|
-
label: "Control"
|
|
50200
|
-
},
|
|
50201
|
-
[_camstack_types.DeviceType.Presence]: {
|
|
50202
|
-
icon: MapPin,
|
|
50203
|
-
label: "Presence"
|
|
50204
|
-
},
|
|
50205
|
-
[_camstack_types.DeviceType.Weather]: {
|
|
50206
|
-
icon: CloudSun,
|
|
50207
|
-
label: "Weather"
|
|
50208
|
-
},
|
|
50209
|
-
[_camstack_types.DeviceType.Vacuum]: {
|
|
50210
|
-
icon: Bot,
|
|
50211
|
-
label: "Vacuum"
|
|
50212
|
-
},
|
|
50213
|
-
[_camstack_types.DeviceType.LawnMower]: {
|
|
50214
|
-
icon: Tractor,
|
|
50215
|
-
label: "Lawn mower"
|
|
50216
|
-
},
|
|
50217
|
-
[_camstack_types.DeviceType.Container]: {
|
|
50218
|
-
icon: Box,
|
|
50219
|
-
label: "Container"
|
|
50220
|
-
},
|
|
50221
|
-
[_camstack_types.DeviceType.Image]: {
|
|
50222
|
-
icon: Image,
|
|
50223
|
-
label: "Image"
|
|
50224
|
-
},
|
|
50225
|
-
[_camstack_types.DeviceType.PetFeeder]: {
|
|
50226
|
-
icon: Bone,
|
|
50227
|
-
label: "Pet feeder"
|
|
50228
|
-
}
|
|
50229
|
-
};
|
|
50230
|
-
var DEVICE_ROLE_META = {
|
|
50231
|
-
[_camstack_types.DeviceRole.Siren]: {
|
|
50232
|
-
icon: Siren,
|
|
50233
|
-
label: "Siren"
|
|
50234
|
-
},
|
|
50235
|
-
[_camstack_types.DeviceRole.Floodlight]: {
|
|
50236
|
-
icon: Lightbulb,
|
|
50237
|
-
label: "Floodlight"
|
|
50238
|
-
},
|
|
50239
|
-
[_camstack_types.DeviceRole.Spotlight]: {
|
|
50240
|
-
icon: Flashlight,
|
|
50241
|
-
label: "Spotlight"
|
|
50242
|
-
},
|
|
50243
|
-
[_camstack_types.DeviceRole.PirSensor]: {
|
|
50244
|
-
icon: Radar,
|
|
50245
|
-
label: "PIR sensor"
|
|
50246
|
-
},
|
|
50247
|
-
[_camstack_types.DeviceRole.Chime]: {
|
|
50248
|
-
icon: Bell,
|
|
50249
|
-
label: "Chime"
|
|
50250
|
-
},
|
|
50251
|
-
[_camstack_types.DeviceRole.Autotrack]: {
|
|
50252
|
-
icon: Crosshair,
|
|
50253
|
-
label: "Auto-track"
|
|
50254
|
-
},
|
|
50255
|
-
[_camstack_types.DeviceRole.Nightvision]: {
|
|
50256
|
-
icon: Moon,
|
|
50257
|
-
label: "Night vision"
|
|
50258
|
-
},
|
|
50259
|
-
[_camstack_types.DeviceRole.PrivacyMask]: {
|
|
50260
|
-
icon: EyeOff,
|
|
50261
|
-
label: "Privacy mask"
|
|
50262
|
-
},
|
|
50263
|
-
[_camstack_types.DeviceRole.Doorbell]: {
|
|
50264
|
-
icon: DoorClosed,
|
|
50265
|
-
label: "Doorbell"
|
|
50266
|
-
},
|
|
50267
|
-
[_camstack_types.DeviceRole.BinaryHelper]: {
|
|
50268
|
-
icon: ToggleLeft,
|
|
50269
|
-
label: "Binary helper"
|
|
50270
|
-
},
|
|
50271
|
-
[_camstack_types.DeviceRole.MotionSensor]: {
|
|
50272
|
-
icon: Footprints,
|
|
50273
|
-
label: "Motion sensor"
|
|
50274
|
-
},
|
|
50275
|
-
[_camstack_types.DeviceRole.ContactSensor]: {
|
|
50276
|
-
icon: DoorOpen,
|
|
50277
|
-
label: "Contact sensor"
|
|
50278
|
-
},
|
|
50279
|
-
[_camstack_types.DeviceRole.LeakSensor]: {
|
|
50280
|
-
icon: Droplet,
|
|
50281
|
-
label: "Leak sensor"
|
|
50282
|
-
},
|
|
50283
|
-
[_camstack_types.DeviceRole.SmokeSensor]: {
|
|
50284
|
-
icon: AlarmSmoke,
|
|
50285
|
-
label: "Smoke sensor"
|
|
50286
|
-
},
|
|
50287
|
-
[_camstack_types.DeviceRole.COSensor]: {
|
|
50288
|
-
icon: Wind,
|
|
50289
|
-
label: "CO sensor"
|
|
50290
|
-
},
|
|
50291
|
-
[_camstack_types.DeviceRole.GasSensor]: {
|
|
50292
|
-
icon: Flame,
|
|
50293
|
-
label: "Gas sensor"
|
|
50294
|
-
},
|
|
50295
|
-
[_camstack_types.DeviceRole.TamperSensor]: {
|
|
50296
|
-
icon: ShieldAlert,
|
|
50297
|
-
label: "Tamper sensor"
|
|
50298
|
-
},
|
|
50299
|
-
[_camstack_types.DeviceRole.VibrationSensor]: {
|
|
50300
|
-
icon: Vibrate,
|
|
50301
|
-
label: "Vibration sensor"
|
|
50302
|
-
},
|
|
50303
|
-
[_camstack_types.DeviceRole.ConnectivitySensor]: {
|
|
50304
|
-
icon: Wifi,
|
|
50305
|
-
label: "Connectivity"
|
|
50306
|
-
},
|
|
50307
|
-
[_camstack_types.DeviceRole.SoundSensor]: {
|
|
50308
|
-
icon: Volume2,
|
|
50309
|
-
label: "Sound sensor"
|
|
50310
|
-
},
|
|
50311
|
-
[_camstack_types.DeviceRole.BinarySensor]: {
|
|
50312
|
-
icon: ToggleLeft,
|
|
50313
|
-
label: "Binary sensor"
|
|
50314
|
-
},
|
|
50315
|
-
[_camstack_types.DeviceRole.TemperatureSensor]: {
|
|
50316
|
-
icon: Thermometer,
|
|
50317
|
-
label: "Temperature"
|
|
50318
|
-
},
|
|
50319
|
-
[_camstack_types.DeviceRole.HumiditySensor]: {
|
|
50320
|
-
icon: Droplets,
|
|
50321
|
-
label: "Humidity"
|
|
50322
|
-
},
|
|
50323
|
-
[_camstack_types.DeviceRole.AmbientLightSensor]: {
|
|
50324
|
-
icon: Sun,
|
|
50325
|
-
label: "Ambient light"
|
|
50326
|
-
},
|
|
50327
|
-
[_camstack_types.DeviceRole.PressureSensor]: {
|
|
50328
|
-
icon: Gauge,
|
|
50329
|
-
label: "Pressure"
|
|
50330
|
-
},
|
|
50331
|
-
[_camstack_types.DeviceRole.WindSensor]: {
|
|
50332
|
-
icon: Wind,
|
|
50333
|
-
label: "Wind"
|
|
50334
|
-
},
|
|
50335
|
-
[_camstack_types.DeviceRole.RainSensor]: {
|
|
50336
|
-
icon: CloudRain,
|
|
50337
|
-
label: "Rain"
|
|
50338
|
-
},
|
|
50339
|
-
[_camstack_types.DeviceRole.UvSensor]: {
|
|
50340
|
-
icon: SunMedium,
|
|
50341
|
-
label: "UV index"
|
|
50342
|
-
},
|
|
50343
|
-
[_camstack_types.DeviceRole.SolarRadiationSensor]: {
|
|
50344
|
-
icon: Sunrise,
|
|
50345
|
-
label: "Solar radiation"
|
|
50346
|
-
},
|
|
50347
|
-
[_camstack_types.DeviceRole.SoilMoistureSensor]: {
|
|
50348
|
-
icon: Sprout,
|
|
50349
|
-
label: "Soil moisture"
|
|
50350
|
-
},
|
|
50351
|
-
[_camstack_types.DeviceRole.PowerSensor]: {
|
|
50352
|
-
icon: Zap,
|
|
50353
|
-
label: "Power"
|
|
50354
|
-
},
|
|
50355
|
-
[_camstack_types.DeviceRole.EnergySensor]: {
|
|
50356
|
-
icon: Zap,
|
|
50357
|
-
label: "Energy"
|
|
50358
|
-
},
|
|
50359
|
-
[_camstack_types.DeviceRole.VoltageSensor]: {
|
|
50360
|
-
icon: Zap,
|
|
50361
|
-
label: "Voltage"
|
|
50362
|
-
},
|
|
50363
|
-
[_camstack_types.DeviceRole.CurrentSensor]: {
|
|
50364
|
-
icon: Zap,
|
|
50365
|
-
label: "Current"
|
|
50366
|
-
},
|
|
50367
|
-
[_camstack_types.DeviceRole.AirQualitySensor]: {
|
|
50368
|
-
icon: Wind,
|
|
50369
|
-
label: "Air quality"
|
|
50370
|
-
},
|
|
50371
|
-
[_camstack_types.DeviceRole.BatterySensor]: {
|
|
50372
|
-
icon: Gauge,
|
|
50373
|
-
label: "Battery"
|
|
50374
|
-
},
|
|
50375
|
-
[_camstack_types.DeviceRole.NumericSensor]: {
|
|
50376
|
-
icon: Hash,
|
|
50377
|
-
label: "Numeric sensor"
|
|
50378
|
-
},
|
|
50379
|
-
[_camstack_types.DeviceRole.EnumSensor]: {
|
|
50380
|
-
icon: List,
|
|
50381
|
-
label: "Enum sensor"
|
|
50382
|
-
},
|
|
50383
|
-
[_camstack_types.DeviceRole.DateTimeSensor]: {
|
|
50384
|
-
icon: Clock,
|
|
50385
|
-
label: "Date / time"
|
|
50386
|
-
},
|
|
50387
|
-
[_camstack_types.DeviceRole.GenericSensor]: {
|
|
50388
|
-
icon: Gauge,
|
|
50389
|
-
label: "Sensor"
|
|
50390
|
-
},
|
|
50391
|
-
[_camstack_types.DeviceRole.NumericControl]: {
|
|
50392
|
-
icon: SlidersHorizontal,
|
|
50393
|
-
label: "Numeric control"
|
|
50394
|
-
},
|
|
50395
|
-
[_camstack_types.DeviceRole.SelectControl]: {
|
|
50396
|
-
icon: ListChecks,
|
|
50397
|
-
label: "Select control"
|
|
50398
|
-
},
|
|
50399
|
-
[_camstack_types.DeviceRole.TextControl]: {
|
|
50400
|
-
icon: Type,
|
|
50401
|
-
label: "Text control"
|
|
50402
|
-
},
|
|
50403
|
-
[_camstack_types.DeviceRole.DateTimeControl]: {
|
|
50404
|
-
icon: Clock,
|
|
50405
|
-
label: "Date / time control"
|
|
50406
|
-
},
|
|
50407
|
-
[_camstack_types.DeviceRole.MobilePushNotifier]: {
|
|
50408
|
-
icon: Smartphone,
|
|
50409
|
-
label: "Mobile push"
|
|
50410
|
-
},
|
|
50411
|
-
[_camstack_types.DeviceRole.MessagingNotifier]: {
|
|
50412
|
-
icon: MessageSquare,
|
|
50413
|
-
label: "Messaging"
|
|
50414
|
-
},
|
|
50415
|
-
[_camstack_types.DeviceRole.EmailNotifier]: {
|
|
50416
|
-
icon: Mail,
|
|
50417
|
-
label: "Email"
|
|
50418
|
-
},
|
|
50419
|
-
[_camstack_types.DeviceRole.GenericNotifier]: {
|
|
50420
|
-
icon: Bell,
|
|
50421
|
-
label: "Notifier"
|
|
50422
|
-
}
|
|
50423
|
-
};
|
|
50424
|
-
var DEVICE_TYPE_VALUES = new Set(Object.values(_camstack_types.DeviceType));
|
|
50425
|
-
var DEVICE_ROLE_VALUES = new Set(Object.values(_camstack_types.DeviceRole));
|
|
50426
|
-
function isDeviceType(value) {
|
|
50427
|
-
return DEVICE_TYPE_VALUES.has(value);
|
|
50428
|
-
}
|
|
50429
|
-
function isDeviceRole(value) {
|
|
50430
|
-
return DEVICE_ROLE_VALUES.has(value);
|
|
50431
|
-
}
|
|
50432
|
-
/** Meta for a known `DeviceType`. */
|
|
50433
|
-
function deviceTypeMeta(type) {
|
|
50434
|
-
return DEVICE_TYPE_META[type];
|
|
50435
|
-
}
|
|
50436
|
-
/** Meta for a known `DeviceRole`. */
|
|
50437
|
-
function deviceRoleMeta(role) {
|
|
50438
|
-
return DEVICE_ROLE_META[role];
|
|
50439
|
-
}
|
|
50440
|
-
var FALLBACK_DEVICE_TYPE_META = DEVICE_TYPE_META[_camstack_types.DeviceType.Generic];
|
|
50441
|
-
var FALLBACK_DEVICE_ROLE_META = DEVICE_ROLE_META[_camstack_types.DeviceRole.GenericSensor];
|
|
50442
|
-
/**
|
|
50443
|
-
* Runtime-string-safe lookup: device data crosses process / network boundaries
|
|
50444
|
-
* as plain strings, so an unrecognised value falls back to the `Generic` meta
|
|
50445
|
-
* instead of throwing.
|
|
50446
|
-
*
|
|
50447
|
-
* This also guards mixed-version module-federation loads where the host
|
|
50448
|
-
* `@camstack/types` enum has a new member before the loaded ui-library bundle
|
|
50449
|
-
* has the matching `DEVICE_TYPE_META` entry.
|
|
50450
|
-
*/
|
|
50451
|
-
function deviceTypeMetaOf(type) {
|
|
50452
|
-
if (!isDeviceType(type)) return FALLBACK_DEVICE_TYPE_META;
|
|
50453
|
-
return DEVICE_TYPE_META[type] ?? FALLBACK_DEVICE_TYPE_META;
|
|
50454
|
-
}
|
|
50455
|
-
/** Runtime-string-safe role lookup; unknown roles fall back to `GenericSensor`. */
|
|
50456
|
-
function deviceRoleMetaOf(role) {
|
|
50457
|
-
if (!isDeviceRole(role)) return FALLBACK_DEVICE_ROLE_META;
|
|
50458
|
-
return DEVICE_ROLE_META[role] ?? FALLBACK_DEVICE_ROLE_META;
|
|
50459
|
-
}
|
|
50460
|
-
/**
|
|
50461
|
-
* Icons an operator may pick for a per-device `display.icon` override (and for
|
|
50462
|
-
* a per-role default), keyed by a stable kebab-case name. Named imports only —
|
|
50463
|
-
* no dynamic indexing into lucide, so the bundle carries exactly this set.
|
|
50464
|
-
* Unknown keys resolve to `undefined` (caller falls through to the next level).
|
|
50465
|
-
*
|
|
50466
|
-
* The vocabulary is the one the VIEWER draws from too (its own icon module,
|
|
50467
|
-
* keyed by these same strings): a key added here that the phone cannot draw
|
|
50468
|
-
* falls through to the next resolution level there, which reads as "my change
|
|
50469
|
-
* did nothing". So the KEY is the contract — a stable kebab-case string, never
|
|
50470
|
-
* a glyph identity — and `device-meta.test.ts` pins that every key resolves
|
|
50471
|
-
* and that the set never loses a key an operator may already have persisted.
|
|
50472
|
-
*
|
|
50473
|
-
* Grouped by what an operator is naming: a device, a light or appliance, a
|
|
50474
|
-
* sensor or the weather it reads, a room, or what moves through it. `gauge2`
|
|
50475
|
-
* is a legacy alias kept for rows that persisted it.
|
|
50476
|
-
*/
|
|
50477
|
-
var DISPLAY_ICON_REGISTRY = {
|
|
50478
|
-
camera: Camera,
|
|
50479
|
-
network: Network,
|
|
50480
|
-
"toggle-left": ToggleLeft,
|
|
50481
|
-
"toggle-right": ToggleRight,
|
|
50482
|
-
"circle-dot": CircleDot,
|
|
50483
|
-
"refresh-cw": RefreshCw,
|
|
50484
|
-
box: Box,
|
|
50485
|
-
"scroll-text": ScrollText,
|
|
50486
|
-
workflow: Workflow,
|
|
50487
|
-
lock: Lock,
|
|
50488
|
-
"lock-open": LockOpen,
|
|
50489
|
-
blinds: Blinds,
|
|
50490
|
-
"air-vent": AirVent,
|
|
50491
|
-
"monitor-play": MonitorPlay,
|
|
50492
|
-
"sliders-horizontal": SlidersHorizontal,
|
|
50493
|
-
"map-pin": MapPin,
|
|
50494
|
-
bot: Bot,
|
|
50495
|
-
tractor: Tractor,
|
|
50496
|
-
image: Image,
|
|
50497
|
-
bone: Bone,
|
|
50498
|
-
"door-closed": DoorClosed,
|
|
50499
|
-
"door-open": DoorOpen,
|
|
50500
|
-
crosshair: Crosshair,
|
|
50501
|
-
eye: Eye,
|
|
50502
|
-
"eye-off": EyeOff,
|
|
50503
|
-
smartphone: Smartphone,
|
|
50504
|
-
phone: Phone,
|
|
50505
|
-
tablet: Tablet,
|
|
50506
|
-
laptop: Laptop,
|
|
50507
|
-
monitor: Monitor,
|
|
50508
|
-
tv: Tv,
|
|
50509
|
-
speaker: Speaker,
|
|
50510
|
-
printer: Printer,
|
|
50511
|
-
projector: Projector,
|
|
50512
|
-
"gamepad-2": Gamepad2,
|
|
50513
|
-
radio: Radio,
|
|
50514
|
-
router: Router,
|
|
50515
|
-
bluetooth: Bluetooth,
|
|
50516
|
-
cpu: Cpu,
|
|
50517
|
-
"hard-drive": HardDrive,
|
|
50518
|
-
server: Server,
|
|
50519
|
-
mic: Mic,
|
|
50520
|
-
"mic-off": MicOff,
|
|
50521
|
-
video: Video,
|
|
50522
|
-
"video-off": VideoOff,
|
|
50523
|
-
music: Music,
|
|
50524
|
-
plug: Plug,
|
|
50525
|
-
"plug-zap": PlugZap,
|
|
50526
|
-
power: Power,
|
|
50527
|
-
"power-off": PowerOff,
|
|
50528
|
-
cable: Cable,
|
|
50529
|
-
battery: Battery,
|
|
50530
|
-
"battery-charging": BatteryCharging,
|
|
50531
|
-
"battery-full": BatteryFull,
|
|
50532
|
-
"battery-low": BatteryLow,
|
|
50533
|
-
key: Key,
|
|
50534
|
-
"key-round": KeyRound,
|
|
50535
|
-
mailbox: Mailbox,
|
|
50536
|
-
package: Package,
|
|
50537
|
-
shield: Shield,
|
|
50538
|
-
"shield-check": ShieldCheck,
|
|
50539
|
-
"shield-off": ShieldOff,
|
|
50540
|
-
lightbulb: Lightbulb,
|
|
50541
|
-
lamp: Lamp,
|
|
50542
|
-
"lamp-ceiling": LampCeiling,
|
|
50543
|
-
"lamp-desk": LampDesk,
|
|
50544
|
-
"lamp-floor": LampFloor,
|
|
50545
|
-
flashlight: Flashlight,
|
|
50546
|
-
heater: Heater,
|
|
50547
|
-
snowflake: Snowflake,
|
|
50548
|
-
"thermometer-sun": ThermometerSun,
|
|
50549
|
-
"thermometer-snowflake": ThermometerSnowflake,
|
|
50550
|
-
refrigerator: Refrigerator,
|
|
50551
|
-
microwave: Microwave,
|
|
50552
|
-
"washing-machine": WashingMachine,
|
|
50553
|
-
"cooking-pot": CookingPot,
|
|
50554
|
-
utensils: Utensils,
|
|
50555
|
-
thermometer: Thermometer,
|
|
50556
|
-
droplets: Droplets,
|
|
50557
|
-
droplet: Droplet,
|
|
50558
|
-
gauge: Gauge,
|
|
50559
|
-
gauge2: Gauge,
|
|
50560
|
-
sun: Sun,
|
|
50561
|
-
"sun-medium": SunMedium,
|
|
50562
|
-
sunrise: Sunrise,
|
|
50563
|
-
moon: Moon,
|
|
50564
|
-
wind: Wind,
|
|
50565
|
-
cloud: Cloud,
|
|
50566
|
-
"cloud-rain": CloudRain,
|
|
50567
|
-
"cloud-sun": CloudSun,
|
|
50568
|
-
waves: Waves,
|
|
50569
|
-
sprout: Sprout,
|
|
50570
|
-
leaf: Leaf,
|
|
50571
|
-
flower: Flower,
|
|
50572
|
-
zap: Zap,
|
|
50573
|
-
flame: Flame,
|
|
50574
|
-
bell: Bell,
|
|
50575
|
-
"bell-ring": BellRing,
|
|
50576
|
-
"bell-off": BellOff,
|
|
50577
|
-
siren: Siren,
|
|
50578
|
-
radar: Radar,
|
|
50579
|
-
activity: Activity,
|
|
50580
|
-
hash: Hash,
|
|
50581
|
-
clock: Clock,
|
|
50582
|
-
timer: Timer,
|
|
50583
|
-
calendar: Calendar,
|
|
50584
|
-
pipette: Pipette,
|
|
50585
|
-
fan: Fan,
|
|
50586
|
-
bath: Bath,
|
|
50587
|
-
footprints: Footprints,
|
|
50588
|
-
"alarm-smoke": AlarmSmoke,
|
|
50589
|
-
"shield-alert": ShieldAlert,
|
|
50590
|
-
vibrate: Vibrate,
|
|
50591
|
-
wifi: Wifi,
|
|
50592
|
-
"wifi-off": WifiOff,
|
|
50593
|
-
"volume-2": Volume2,
|
|
50594
|
-
"volume-x": VolumeX,
|
|
50595
|
-
heart: Heart,
|
|
50596
|
-
"heart-pulse": HeartPulse,
|
|
50597
|
-
star: Star,
|
|
50598
|
-
sparkles: Sparkles,
|
|
50599
|
-
house: House,
|
|
50600
|
-
sofa: Sofa,
|
|
50601
|
-
"bed-double": BedDouble,
|
|
50602
|
-
bed: Bed,
|
|
50603
|
-
warehouse: Warehouse,
|
|
50604
|
-
trees: Trees,
|
|
50605
|
-
"tree-pine": TreePine,
|
|
50606
|
-
fence: Fence,
|
|
50607
|
-
store: Store,
|
|
50608
|
-
building: Building,
|
|
50609
|
-
"building-2": Building2,
|
|
50610
|
-
mountain: Mountain,
|
|
50611
|
-
umbrella: Umbrella,
|
|
50612
|
-
dumbbell: Dumbbell,
|
|
50613
|
-
wrench: Wrench,
|
|
50614
|
-
hammer: Hammer,
|
|
50615
|
-
drill: Drill,
|
|
50616
|
-
"waves-ladder": WavesLadder,
|
|
50617
|
-
"circle-parking": CircleParking,
|
|
50618
|
-
briefcase: Briefcase,
|
|
50619
|
-
route: Route,
|
|
50620
|
-
car: Car,
|
|
50621
|
-
bike: Bike,
|
|
50622
|
-
bus: Bus,
|
|
50623
|
-
truck: Truck,
|
|
50624
|
-
plane: Plane,
|
|
50625
|
-
"train-front": TrainFront,
|
|
50626
|
-
sailboat: Sailboat,
|
|
50627
|
-
dog: Dog,
|
|
50628
|
-
cat: Cat,
|
|
50629
|
-
bird: Bird,
|
|
50630
|
-
"paw-print": PawPrint,
|
|
50631
|
-
baby: Baby,
|
|
50632
|
-
user: User,
|
|
50633
|
-
users: Users,
|
|
50634
|
-
"person-standing": PersonStanding
|
|
50635
|
-
};
|
|
50636
|
-
/** Resolve a `display.icon` name to a lucide component, or `undefined` when the
|
|
50637
|
-
* name is not in the curated `DISPLAY_ICON_REGISTRY`. */
|
|
50638
|
-
function resolveDisplayIcon(name) {
|
|
50639
|
-
return Object.hasOwn(DISPLAY_ICON_REGISTRY, name) ? DISPLAY_ICON_REGISTRY[name] : void 0;
|
|
50640
|
-
}
|
|
50641
|
-
/**
|
|
50642
|
-
* EXHAUSTIVE device-type filter options — one entry per `DeviceType` member,
|
|
50643
|
-
* derived from `DEVICE_TYPE_META` so the set is always complete and a newly
|
|
50644
|
-
* added `DeviceType` automatically appears in every type filter (Devices page,
|
|
50645
|
-
* adoption modal, …) without touching any consumer.
|
|
50646
|
-
*
|
|
50647
|
-
* The previous per-consumer logic built options from the types PRESENT in the
|
|
50648
|
-
* list (or a hand-maintained subset), so recently-added types (vacuum, lawn
|
|
50649
|
-
* mower, valve, humidifier, water heater, weather, image, …) were silently
|
|
50650
|
-
* missing from the dropdown. This is the single source of truth instead.
|
|
50651
|
-
*
|
|
50652
|
-
* `id` is the raw `DeviceType` string (matches the filtering predicate, which
|
|
50653
|
-
* compares against `device.type`); `label` + `icon` come from the meta map.
|
|
50654
|
-
* Ordered by `DeviceType` declaration order for a stable, intentional layout.
|
|
50655
|
-
*/
|
|
50656
|
-
var ALL_DEVICE_TYPE_FILTER_OPTIONS = Object.values(_camstack_types.DeviceType).map((type) => {
|
|
50657
|
-
const meta = deviceTypeMetaOf(type);
|
|
50658
|
-
return {
|
|
50659
|
-
id: type,
|
|
50660
|
-
label: meta.label,
|
|
50661
|
-
icon: meta.icon
|
|
50662
|
-
};
|
|
50663
|
-
});
|
|
50664
|
-
function allDeviceTypeFilterOptions() {
|
|
50665
|
-
return ALL_DEVICE_TYPE_FILTER_OPTIONS;
|
|
50666
|
-
}
|
|
50667
|
-
//#endregion
|
|
50668
50898
|
//#region src/hooks/use-debounced-string.ts
|
|
50669
50899
|
/**
|
|
50670
50900
|
* useDebouncedString — return `value` after `delay` ms have passed
|
|
@@ -50683,6 +50913,59 @@ function useDebouncedString(value, delayMs) {
|
|
|
50683
50913
|
return debounced;
|
|
50684
50914
|
}
|
|
50685
50915
|
//#endregion
|
|
50916
|
+
//#region src/hooks/use-persisted-page-size.ts
|
|
50917
|
+
/**
|
|
50918
|
+
* usePersistedPageSize — a "rows per page" choice remembered per viewer.
|
|
50919
|
+
*
|
|
50920
|
+
* The caller names the storage key, the allowed sizes and the default. Each
|
|
50921
|
+
* surface with its own default or option set keeps its own key, so one
|
|
50922
|
+
* surface's choice never lands on another that cannot show it (the device
|
|
50923
|
+
* list's global key stays `useDeviceListPageSize`'s, with its own options).
|
|
50924
|
+
*
|
|
50925
|
+
* `PAGE_SIZE_ALL` (0) is the "All" option: one page holding every row.
|
|
50926
|
+
*
|
|
50927
|
+
* Storage is a convenience, never a requirement: every read and write is
|
|
50928
|
+
* guarded, and a blocked / private-mode / missing storage simply means the
|
|
50929
|
+
* choice lasts until the page is left. A stored value that is not one of the
|
|
50930
|
+
* options (an older option set, a hand-edited value) is ignored.
|
|
50931
|
+
*/
|
|
50932
|
+
/** The "All" option — one page holding every row. */
|
|
50933
|
+
var PAGE_SIZE_ALL = 0;
|
|
50934
|
+
function readStored(key, options, fallback) {
|
|
50935
|
+
if (key === null || typeof window === "undefined") return fallback;
|
|
50936
|
+
try {
|
|
50937
|
+
const raw = window.localStorage.getItem(key);
|
|
50938
|
+
if (raw === null) return fallback;
|
|
50939
|
+
const parsed = Number.parseInt(raw, 10);
|
|
50940
|
+
return Number.isFinite(parsed) && options.includes(parsed) ? parsed : fallback;
|
|
50941
|
+
} catch {
|
|
50942
|
+
return fallback;
|
|
50943
|
+
}
|
|
50944
|
+
}
|
|
50945
|
+
function writeStored(key, value) {
|
|
50946
|
+
if (key === null || typeof window === "undefined") return;
|
|
50947
|
+
try {
|
|
50948
|
+
window.localStorage.setItem(key, String(value));
|
|
50949
|
+
} catch {}
|
|
50950
|
+
}
|
|
50951
|
+
/** @returns `[size, setSize]`; `setSize` ignores a size that is not an option. */
|
|
50952
|
+
function usePersistedPageSize({ storageKey, options, defaultSize }) {
|
|
50953
|
+
const seed = options.includes(defaultSize) ? defaultSize : options[0] ?? defaultSize;
|
|
50954
|
+
const [size, setSize] = (0, react$1.useState)(() => readStored(storageKey, options, seed));
|
|
50955
|
+
return [size, (0, react$1.useCallback)((next) => {
|
|
50956
|
+
if (!options.includes(next)) return;
|
|
50957
|
+
setSize(next);
|
|
50958
|
+
writeStored(storageKey, next);
|
|
50959
|
+
}, [options, storageKey])];
|
|
50960
|
+
}
|
|
50961
|
+
/**
|
|
50962
|
+
* The number of rows one page holds for a chosen size: "All" is every row
|
|
50963
|
+
* (at least 1, so the pager arithmetic never divides by zero).
|
|
50964
|
+
*/
|
|
50965
|
+
function effectivePageSize(size, totalItems) {
|
|
50966
|
+
return size === 0 ? Math.max(1, totalItems) : size;
|
|
50967
|
+
}
|
|
50968
|
+
//#endregion
|
|
50686
50969
|
//#region src/hooks/use-device-list-page-size.ts
|
|
50687
50970
|
/**
|
|
50688
50971
|
* useDeviceListPageSize — global page-size preference for the device-list
|
|
@@ -50693,8 +50976,9 @@ function useDebouncedString(value, delayMs) {
|
|
|
50693
50976
|
* value is validated against {@link DEVICE_LIST_PAGE_SIZE_OPTIONS}; any
|
|
50694
50977
|
* garbage / out-of-range value falls back to the provided default.
|
|
50695
50978
|
*
|
|
50696
|
-
*
|
|
50697
|
-
* a
|
|
50979
|
+
* A thin binding of `usePersistedPageSize` to that key and option set; a
|
|
50980
|
+
* surface with a different default or options uses the generic hook with a
|
|
50981
|
+
* key of its own.
|
|
50698
50982
|
*/
|
|
50699
50983
|
/** Selectable per-page sizes. The table default (50) is intentionally one of them. */
|
|
50700
50984
|
var DEVICE_LIST_PAGE_SIZE_OPTIONS = [
|
|
@@ -50705,33 +50989,6 @@ var DEVICE_LIST_PAGE_SIZE_OPTIONS = [
|
|
|
50705
50989
|
];
|
|
50706
50990
|
/** Single global key shared across every device-list surface. */
|
|
50707
50991
|
var DEVICE_LIST_PAGE_SIZE_KEY = "camstack.device-list.pageSize";
|
|
50708
|
-
function isAllowed(value) {
|
|
50709
|
-
return DEVICE_LIST_PAGE_SIZE_OPTIONS.includes(value);
|
|
50710
|
-
}
|
|
50711
|
-
/**
|
|
50712
|
-
* Normalize a caller-supplied `defaultSize` to an allowed option, falling back
|
|
50713
|
-
* to the canonical default so a stray value can never seed a phantom size.
|
|
50714
|
-
*/
|
|
50715
|
-
function safeDefault(defaultSize) {
|
|
50716
|
-
return isAllowed(defaultSize) ? defaultSize : 50;
|
|
50717
|
-
}
|
|
50718
|
-
function readStored(defaultSize) {
|
|
50719
|
-
if (typeof window === "undefined") return defaultSize;
|
|
50720
|
-
try {
|
|
50721
|
-
const raw = window.localStorage.getItem(DEVICE_LIST_PAGE_SIZE_KEY);
|
|
50722
|
-
if (raw === null) return defaultSize;
|
|
50723
|
-
const parsed = Number.parseInt(raw, 10);
|
|
50724
|
-
return Number.isFinite(parsed) && isAllowed(parsed) ? parsed : defaultSize;
|
|
50725
|
-
} catch {
|
|
50726
|
-
return defaultSize;
|
|
50727
|
-
}
|
|
50728
|
-
}
|
|
50729
|
-
function writeStored(value) {
|
|
50730
|
-
if (typeof window === "undefined") return;
|
|
50731
|
-
try {
|
|
50732
|
-
window.localStorage.setItem(DEVICE_LIST_PAGE_SIZE_KEY, String(value));
|
|
50733
|
-
} catch {}
|
|
50734
|
-
}
|
|
50735
50992
|
/**
|
|
50736
50993
|
* @param defaultSize fallback when nothing valid is stored. If it is not itself
|
|
50737
50994
|
* a member of {@link DEVICE_LIST_PAGE_SIZE_OPTIONS}, it is replaced by
|
|
@@ -50739,13 +50996,11 @@ function writeStored(value) {
|
|
|
50739
50996
|
* @returns `[size, setSize]` — `setSize` ignores values outside the allowed set.
|
|
50740
50997
|
*/
|
|
50741
50998
|
function useDeviceListPageSize(defaultSize) {
|
|
50742
|
-
|
|
50743
|
-
|
|
50744
|
-
|
|
50745
|
-
|
|
50746
|
-
|
|
50747
|
-
writeStored(next);
|
|
50748
|
-
}, [])];
|
|
50999
|
+
return usePersistedPageSize({
|
|
51000
|
+
storageKey: DEVICE_LIST_PAGE_SIZE_KEY,
|
|
51001
|
+
options: DEVICE_LIST_PAGE_SIZE_OPTIONS,
|
|
51002
|
+
defaultSize: DEVICE_LIST_PAGE_SIZE_OPTIONS.includes(defaultSize) ? defaultSize : 50
|
|
51003
|
+
});
|
|
50749
51004
|
}
|
|
50750
51005
|
//#endregion
|
|
50751
51006
|
//#region src/composites/device-item/helpers.ts
|
|
@@ -53043,6 +53298,29 @@ function groupTopLevelAndAccessories(devices, options) {
|
|
|
53043
53298
|
};
|
|
53044
53299
|
}
|
|
53045
53300
|
//#endregion
|
|
53301
|
+
//#region src/composites/device-list/page-size-select.tsx
|
|
53302
|
+
function pageSizeLabel(size) {
|
|
53303
|
+
return size === 0 ? "All" : String(size);
|
|
53304
|
+
}
|
|
53305
|
+
function PageSizeSelect({ value, options, onChange, ariaLabel }) {
|
|
53306
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
53307
|
+
className: "inline-flex items-center gap-1.5",
|
|
53308
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
53309
|
+
"aria-hidden": "true",
|
|
53310
|
+
children: "Per page"
|
|
53311
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
53312
|
+
"aria-label": ariaLabel,
|
|
53313
|
+
value,
|
|
53314
|
+
onChange: (e) => onChange(Number.parseInt(e.target.value, 10)),
|
|
53315
|
+
className: "h-7 px-1.5 rounded-md border border-border bg-surface text-[11px] text-foreground focus:outline-none focus:ring-1 focus:ring-primary/40",
|
|
53316
|
+
children: options.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
53317
|
+
value: opt,
|
|
53318
|
+
children: pageSizeLabel(opt)
|
|
53319
|
+
}, opt))
|
|
53320
|
+
})]
|
|
53321
|
+
});
|
|
53322
|
+
}
|
|
53323
|
+
//#endregion
|
|
53046
53324
|
//#region src/composites/device-list/multi-select.tsx
|
|
53047
53325
|
/**
|
|
53048
53326
|
* Compact multi-select dropdown — a single chip-sized trigger ("Label · N")
|
|
@@ -53957,23 +54235,11 @@ function DeviceModeList(props) {
|
|
|
53957
54235
|
totalItems,
|
|
53958
54236
|
" ",
|
|
53959
54237
|
totalItems === 1 ? "device" : "devices"
|
|
53960
|
-
] }), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
53961
|
-
|
|
53962
|
-
|
|
53963
|
-
|
|
53964
|
-
|
|
53965
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
53966
|
-
"aria-label": "Devices per page",
|
|
53967
|
-
value: tablePageSize,
|
|
53968
|
-
onChange: (e) => {
|
|
53969
|
-
setTablePageSize(Number.parseInt(e.target.value, 10));
|
|
53970
|
-
},
|
|
53971
|
-
className: "h-7 px-1.5 rounded-md border border-border bg-surface text-[11px] text-foreground focus:outline-none focus:ring-1 focus:ring-primary/40",
|
|
53972
|
-
children: DEVICE_LIST_PAGE_SIZE_OPTIONS.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
53973
|
-
value: opt,
|
|
53974
|
-
children: opt
|
|
53975
|
-
}, opt))
|
|
53976
|
-
})]
|
|
54238
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageSizeSelect, {
|
|
54239
|
+
ariaLabel: "Devices per page",
|
|
54240
|
+
value: tablePageSize,
|
|
54241
|
+
options: DEVICE_LIST_PAGE_SIZE_OPTIONS,
|
|
54242
|
+
onChange: setTablePageSize
|
|
53977
54243
|
})]
|
|
53978
54244
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pagination, {
|
|
53979
54245
|
currentPage: safePage,
|
|
@@ -54017,6 +54283,7 @@ function useDeviceListRealtimeSync() {
|
|
|
54017
54283
|
}
|
|
54018
54284
|
//#endregion
|
|
54019
54285
|
//#region src/composites/device-list/generic-mode.tsx
|
|
54286
|
+
var FIXED_PAGE_SIZE = 100;
|
|
54020
54287
|
/**
|
|
54021
54288
|
* Generic render-prop list: search + pagination chrome shared with the device
|
|
54022
54289
|
* list, over an arbitrary item type. Local (non-URL) state — intended for
|
|
@@ -54024,7 +54291,12 @@ function useDeviceListRealtimeSync() {
|
|
|
54024
54291
|
* `renderItem`.
|
|
54025
54292
|
*/
|
|
54026
54293
|
function GenericModeList(props) {
|
|
54027
|
-
const { items, getKey, getSearchText, renderItem, getFilterType, mapFilterOption, filterOptions, filterLabel = "Type", initialTypeFilters = [], columns, renderExpanded, isExpanded, rowClassName, onRowClick, isLoading = false, searchPlaceholder = "Search", emptyLabel = "No items found.", pageSize =
|
|
54294
|
+
const { items, getKey, getSearchText, renderItem, getFilterType, mapFilterOption, filterOptions, filterLabel = "Type", initialTypeFilters = [], columns, renderExpanded, isExpanded, rowClassName, onRowClick, isLoading = false, searchPlaceholder = "Search", emptyLabel = "No items found.", pageSize: fixedPageSize = FIXED_PAGE_SIZE, pageSizeSelector, toolbar } = props;
|
|
54295
|
+
const [chosenPageSize, setChosenPageSize] = usePersistedPageSize(pageSizeSelector ?? {
|
|
54296
|
+
storageKey: null,
|
|
54297
|
+
options: [fixedPageSize],
|
|
54298
|
+
defaultSize: fixedPageSize
|
|
54299
|
+
});
|
|
54028
54300
|
const [searchInput, setSearchInput] = (0, react$1.useState)("");
|
|
54029
54301
|
const debouncedSearch = useDebouncedString(searchInput, 300);
|
|
54030
54302
|
const [typeFilters, setTypeFilters] = (0, react$1.useState)(() => [...initialTypeFilters]);
|
|
@@ -54073,6 +54345,7 @@ function GenericModeList(props) {
|
|
|
54073
54345
|
getFilterType
|
|
54074
54346
|
]);
|
|
54075
54347
|
const totalItems = filtered.length;
|
|
54348
|
+
const pageSize = pageSizeSelector ? effectivePageSize(chosenPageSize, totalItems) : fixedPageSize;
|
|
54076
54349
|
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
54077
54350
|
const safePage = Math.min(page, totalPages);
|
|
54078
54351
|
const startIdx = (safePage - 1) * pageSize;
|
|
@@ -54156,7 +54429,23 @@ function GenericModeList(props) {
|
|
|
54156
54429
|
}),
|
|
54157
54430
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
54158
54431
|
className: "shrink-0",
|
|
54159
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
54432
|
+
children: pageSizeSelector && totalItems > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
54433
|
+
className: "flex items-center justify-between gap-4 flex-wrap pt-2 text-[11px] text-foreground-subtle",
|
|
54434
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
54435
|
+
className: "inline-flex items-center gap-2",
|
|
54436
|
+
children: [totalItems <= pageSize && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [totalItems, " total"] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PageSizeSelect, {
|
|
54437
|
+
ariaLabel: "Rows per page",
|
|
54438
|
+
value: chosenPageSize,
|
|
54439
|
+
options: pageSizeSelector.options,
|
|
54440
|
+
onChange: setChosenPageSize
|
|
54441
|
+
})]
|
|
54442
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pagination, {
|
|
54443
|
+
currentPage: safePage,
|
|
54444
|
+
totalItems,
|
|
54445
|
+
pageSize,
|
|
54446
|
+
onPageChange: setPage
|
|
54447
|
+
})]
|
|
54448
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pagination, {
|
|
54160
54449
|
currentPage: safePage,
|
|
54161
54450
|
totalItems,
|
|
54162
54451
|
pageSize,
|
|
@@ -54285,6 +54574,24 @@ var DeviceItemRowSchema = zod.z.object({
|
|
|
54285
54574
|
});
|
|
54286
54575
|
var SupportedKindsSchema = zod.z.array(zod.z.string());
|
|
54287
54576
|
var STATUS_POLL_INTERVAL_MS = 1e4;
|
|
54577
|
+
/** Where the viewer's "rows per page" choice for this table is remembered. */
|
|
54578
|
+
var DEVICE_EXPORT_PAGE_SIZE_KEY = "camstack.device-export.pageSize";
|
|
54579
|
+
/**
|
|
54580
|
+
* The exposed-devices table's page sizes. Its own key and options, not the
|
|
54581
|
+
* Devices page's (25/50/100/200, default 50): the operator asked for a short
|
|
54582
|
+
* default here (25) and an "All" for a quick scan of every exportable device.
|
|
54583
|
+
*/
|
|
54584
|
+
var DEVICE_EXPORT_PAGE_SIZE = {
|
|
54585
|
+
options: [
|
|
54586
|
+
10,
|
|
54587
|
+
25,
|
|
54588
|
+
50,
|
|
54589
|
+
100,
|
|
54590
|
+
0
|
|
54591
|
+
],
|
|
54592
|
+
defaultSize: 25,
|
|
54593
|
+
storageKey: DEVICE_EXPORT_PAGE_SIZE_KEY
|
|
54594
|
+
};
|
|
54288
54595
|
/**
|
|
54289
54596
|
* The fleet-list poll. Deliberately the same 30 s as the window
|
|
54290
54597
|
* `applyFleetQueryDefaults` registers for `deviceManager.listAll` (D274) —
|
|
@@ -54369,6 +54676,35 @@ function SetupSection({ setup }) {
|
|
|
54369
54676
|
})]
|
|
54370
54677
|
});
|
|
54371
54678
|
}
|
|
54679
|
+
/** Parse `getStatus` against the canonical cap schema (loose wire output). */
|
|
54680
|
+
function parseStatus(data) {
|
|
54681
|
+
const parsed = _camstack_types.DeviceExportStatusSchema.safeParse(data);
|
|
54682
|
+
return parsed.success ? parsed.data : null;
|
|
54683
|
+
}
|
|
54684
|
+
/**
|
|
54685
|
+
* The exporter's error and Setup block on their own — for a page that shows
|
|
54686
|
+
* them above its settings while the devices table sits at the bottom. Renders
|
|
54687
|
+
* nothing when the exporter reports neither. Shares `getStatus`'s query key
|
|
54688
|
+
* with the panel, so mounting both costs one request.
|
|
54689
|
+
*/
|
|
54690
|
+
function DeviceExportSetup({ addonId }) {
|
|
54691
|
+
const statusQuery = useDeviceExportGetStatus({
|
|
54692
|
+
nodeId: "hub",
|
|
54693
|
+
addonId
|
|
54694
|
+
}, {
|
|
54695
|
+
refetchInterval: STATUS_POLL_INTERVAL_MS,
|
|
54696
|
+
retry: false
|
|
54697
|
+
});
|
|
54698
|
+
const status = (0, react$1.useMemo)(() => parseStatus(statusQuery.data), [statusQuery.data]);
|
|
54699
|
+
if (!status?.error && !status?.setup) return null;
|
|
54700
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
54701
|
+
className: "rounded-lg border border-border bg-surface overflow-hidden",
|
|
54702
|
+
children: [status.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
54703
|
+
className: "px-2 sm:px-4 py-3 border-b border-border",
|
|
54704
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBox, { message: status.error })
|
|
54705
|
+
}), status.setup && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupSection, { setup: status.setup })]
|
|
54706
|
+
});
|
|
54707
|
+
}
|
|
54372
54708
|
/**
|
|
54373
54709
|
* Per-row Expose/Exposed toggle. Reflects whether the row's device is exposed
|
|
54374
54710
|
* to THIS exporter and flips it through the SAME runner the bulk buttons use —
|
|
@@ -54447,7 +54783,7 @@ function BulkSummary({ outcome, onDismiss }) {
|
|
|
54447
54783
|
* Generic device-export panel. Addon-agnostic — only the `device-export`
|
|
54448
54784
|
* cap drives it.
|
|
54449
54785
|
*/
|
|
54450
|
-
function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
54786
|
+
function DeviceExportPanel({ addonId, onOpenDevice, showSetup = true }) {
|
|
54451
54787
|
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
54452
54788
|
const statusQuery = useDeviceExportGetStatus({
|
|
54453
54789
|
nodeId: "hub",
|
|
@@ -54473,10 +54809,7 @@ function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
|
54473
54809
|
}, [queryClient]);
|
|
54474
54810
|
const exposeMutation = useDeviceExportExposeDevice({ onSuccess: invalidate });
|
|
54475
54811
|
const unexposeMutation = useDeviceExportUnexposeDevice({ onSuccess: invalidate });
|
|
54476
|
-
const status = (0, react$1.useMemo)(() =>
|
|
54477
|
-
const parsed = _camstack_types.DeviceExportStatusSchema.safeParse(statusQuery.data);
|
|
54478
|
-
return parsed.success ? parsed.data : null;
|
|
54479
|
-
}, [statusQuery.data]);
|
|
54812
|
+
const status = (0, react$1.useMemo)(() => parseStatus(statusQuery.data), [statusQuery.data]);
|
|
54480
54813
|
const exposed = (0, react$1.useMemo)(() => {
|
|
54481
54814
|
const parsed = ExposedDeviceArraySchema.safeParse(exposedQuery.data);
|
|
54482
54815
|
return parsed.success ? parsed.data : [];
|
|
@@ -54699,11 +55032,11 @@ function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
|
54699
55032
|
]
|
|
54700
55033
|
}), loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin text-foreground-subtle" })]
|
|
54701
55034
|
}),
|
|
54702
|
-
status?.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55035
|
+
showSetup && status?.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
54703
55036
|
className: "px-2 sm:px-4 py-3 border-b border-border",
|
|
54704
55037
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBox, { message: status.error })
|
|
54705
55038
|
}),
|
|
54706
|
-
status?.setup && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupSection, { setup: status.setup }),
|
|
55039
|
+
showSetup && status?.setup && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupSection, { setup: status.setup }),
|
|
54707
55040
|
outcome !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BulkSummary, {
|
|
54708
55041
|
outcome,
|
|
54709
55042
|
onDismiss: dismissOutcome
|
|
@@ -54723,6 +55056,7 @@ function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
|
54723
55056
|
columns,
|
|
54724
55057
|
onRowClick: onOpenDevice ? onRowClick : void 0,
|
|
54725
55058
|
toolbar: selectionToolbar,
|
|
55059
|
+
pageSizeSelector: DEVICE_EXPORT_PAGE_SIZE,
|
|
54726
55060
|
searchPlaceholder: "Search by name or stableId",
|
|
54727
55061
|
emptyLabel: "No device matches this search."
|
|
54728
55062
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, {
|
|
@@ -54748,145 +55082,6 @@ function DeviceGrid({ children, minCardWidth = 220, gap = 3, className }) {
|
|
|
54748
55082
|
});
|
|
54749
55083
|
}
|
|
54750
55084
|
//#endregion
|
|
54751
|
-
//#region src/composites/icon-picker.tsx
|
|
54752
|
-
/**
|
|
54753
|
-
* icon-picker — the ONE control for choosing an icon, wherever admin-ui asks.
|
|
54754
|
-
*
|
|
54755
|
-
* There were two: a device one over `DISPLAY_ICON_REGISTRY` and a room one
|
|
54756
|
-
* over `LOCATION_ICON_IDS`, identical apart from the vocabulary they walked.
|
|
54757
|
-
* That was tolerable while the device set was 56 glyphs in a flat grid. It is
|
|
54758
|
-
* not at 157: a picker that only lets the operator HUNT is a picker they stop
|
|
54759
|
-
* using, and the two copies were already drifting — only one of them had an
|
|
54760
|
-
* i18n'd label.
|
|
54761
|
-
*
|
|
54762
|
-
* So the vocabulary, the grouping and the search all come from
|
|
54763
|
-
* `@camstack/types`' `display-icon-vocabulary`, which is the same module the
|
|
54764
|
-
* viewer's sheet searches. What is left here is the web half: a popover, a
|
|
54765
|
-
* grid, and a text field.
|
|
54766
|
-
*
|
|
54767
|
-
* ## What it does NOT own
|
|
54768
|
-
*
|
|
54769
|
-
* - **The glyphs.** `resolveGlyph` is a prop, because this package's table is
|
|
54770
|
-
* `lucide-react` and the viewer's is `lucide-react-native`. A key this build
|
|
54771
|
-
* cannot draw is SKIPPED rather than rendered as a hole — an empty tile
|
|
54772
|
-
* reads as a rendering bug, not as a missing choice.
|
|
54773
|
-
* - **The words.** Every string is a prop. This package has no i18n (one file
|
|
54774
|
-
* in it imports react-i18next, and that is the exception), and a control
|
|
54775
|
-
* that reached for a translation would force it on every consumer.
|
|
54776
|
-
* - **The write.** `onPick` is called and that is all; whether it is a form
|
|
54777
|
-
* value or an immediate mutation is the caller's business, as it already was
|
|
54778
|
-
* in both pickers this replaces.
|
|
54779
|
-
*
|
|
54780
|
-
* ## The clear tile is never filtered away
|
|
54781
|
-
*
|
|
54782
|
-
* The "inherit" / "no icon" choice sits above the sections and ignores the
|
|
54783
|
-
* search. A query that hid it would strand the operator on a glyph they picked
|
|
54784
|
-
* by accident with no way back to the default — the one action a picker must
|
|
54785
|
-
* always offer.
|
|
54786
|
-
*/
|
|
54787
|
-
function IconPicker({ value, onPick, resolveGlyph, fallbackGlyph, labels, only, extraWords, clearGlyph, labelFor, disabled = false }) {
|
|
54788
|
-
const [open, setOpen] = (0, react$1.useState)(false);
|
|
54789
|
-
const [query, setQuery] = (0, react$1.useState)("");
|
|
54790
|
-
const allowed = (0, react$1.useMemo)(() => only === void 0 ? null : new Set(only), [only]);
|
|
54791
|
-
const sections = (0, react$1.useMemo)(() => {
|
|
54792
|
-
const hits = (0, _camstack_types.searchDisplayIcons)(query, extraWords);
|
|
54793
|
-
const byGroup = /* @__PURE__ */ new Map();
|
|
54794
|
-
for (const hit of hits) {
|
|
54795
|
-
const { key, group } = hit.entry;
|
|
54796
|
-
if (allowed !== null && !allowed.has(key)) continue;
|
|
54797
|
-
if (resolveGlyph(key) === void 0) continue;
|
|
54798
|
-
const bucket = byGroup.get(group);
|
|
54799
|
-
if (bucket === void 0) byGroup.set(group, [key]);
|
|
54800
|
-
else bucket.push(key);
|
|
54801
|
-
}
|
|
54802
|
-
return _camstack_types.DISPLAY_ICON_GROUPS.flatMap((group) => {
|
|
54803
|
-
const keys = byGroup.get(group);
|
|
54804
|
-
return keys === void 0 || keys.length === 0 ? [] : [{
|
|
54805
|
-
group,
|
|
54806
|
-
keys
|
|
54807
|
-
}];
|
|
54808
|
-
});
|
|
54809
|
-
}, [
|
|
54810
|
-
query,
|
|
54811
|
-
extraWords,
|
|
54812
|
-
allowed,
|
|
54813
|
-
resolveGlyph
|
|
54814
|
-
]);
|
|
54815
|
-
const Current = (value === null ? void 0 : resolveGlyph(value)) ?? fallbackGlyph;
|
|
54816
|
-
const choose = async (next) => {
|
|
54817
|
-
setOpen(false);
|
|
54818
|
-
setQuery("");
|
|
54819
|
-
await onPick(next);
|
|
54820
|
-
};
|
|
54821
|
-
const Clear = clearGlyph ?? fallbackGlyph;
|
|
54822
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
54823
|
-
className: "relative flex shrink-0 items-center gap-2",
|
|
54824
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
54825
|
-
type: "button",
|
|
54826
|
-
disabled,
|
|
54827
|
-
onClick: () => setOpen((o) => !o),
|
|
54828
|
-
"aria-expanded": open,
|
|
54829
|
-
"aria-label": labels.trigger,
|
|
54830
|
-
title: labels.trigger,
|
|
54831
|
-
className: "rounded border border-border p-1 text-foreground-muted hover:bg-surface-hover disabled:opacity-50",
|
|
54832
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Current, { className: "h-4 w-4" })
|
|
54833
|
-
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
54834
|
-
type: "button",
|
|
54835
|
-
"aria-label": labels.close,
|
|
54836
|
-
onClick: () => setOpen(false),
|
|
54837
|
-
className: "fixed inset-0 z-10 cursor-default"
|
|
54838
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
54839
|
-
role: "group",
|
|
54840
|
-
"aria-label": labels.panel,
|
|
54841
|
-
className: "absolute left-0 top-full z-20 mt-1 max-h-80 w-72 overflow-y-auto rounded-md border border-border bg-surface p-2 shadow-lg",
|
|
54842
|
-
children: [
|
|
54843
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
54844
|
-
type: "search",
|
|
54845
|
-
value: query,
|
|
54846
|
-
autoFocus: true,
|
|
54847
|
-
onChange: (e) => setQuery(e.target.value),
|
|
54848
|
-
placeholder: labels.searchPlaceholder,
|
|
54849
|
-
"aria-label": labels.searchPlaceholder,
|
|
54850
|
-
className: "mb-2 w-full rounded border border-border bg-surface-raised px-2 py-1 text-xs text-foreground placeholder:text-foreground-subtle"
|
|
54851
|
-
}),
|
|
54852
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
54853
|
-
type: "button",
|
|
54854
|
-
onClick: () => void choose(null),
|
|
54855
|
-
"aria-pressed": value === null,
|
|
54856
|
-
className: "mb-2 flex w-full items-center gap-1.5 rounded px-1.5 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover",
|
|
54857
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Clear, { className: "h-3.5 w-3.5" }), labels.clear]
|
|
54858
|
-
}),
|
|
54859
|
-
sections.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
54860
|
-
className: "px-1.5 py-2 text-[11px] text-foreground-subtle",
|
|
54861
|
-
children: labels.noMatches
|
|
54862
|
-
}) : sections.map(({ group, keys }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
54863
|
-
className: "mb-2 last:mb-0",
|
|
54864
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
54865
|
-
className: "px-1.5 pb-1 text-[10px] uppercase tracking-wide text-foreground-subtle",
|
|
54866
|
-
children: labels.groups[group]
|
|
54867
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
54868
|
-
className: "grid grid-cols-7 gap-1",
|
|
54869
|
-
children: keys.map((key) => {
|
|
54870
|
-
const Glyph = resolveGlyph(key);
|
|
54871
|
-
if (Glyph === void 0) return null;
|
|
54872
|
-
const selected = value === key;
|
|
54873
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
54874
|
-
type: "button",
|
|
54875
|
-
onClick: () => void choose(key),
|
|
54876
|
-
"aria-pressed": selected,
|
|
54877
|
-
"aria-label": labelFor?.(key) ?? key,
|
|
54878
|
-
title: labelFor?.(key) ?? key,
|
|
54879
|
-
className: selected ? "flex items-center justify-center rounded border border-primary bg-primary/10 p-1.5 text-foreground" : "flex items-center justify-center rounded border border-transparent p-1.5 text-foreground-muted hover:bg-surface-hover",
|
|
54880
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Glyph, { className: "h-4 w-4" })
|
|
54881
|
-
}, key);
|
|
54882
|
-
})
|
|
54883
|
-
})]
|
|
54884
|
-
}, group))
|
|
54885
|
-
]
|
|
54886
|
-
})] })]
|
|
54887
|
-
});
|
|
54888
|
-
}
|
|
54889
|
-
//#endregion
|
|
54890
55085
|
//#region src/composites/device-selector-picker.tsx
|
|
54891
55086
|
/**
|
|
54892
55087
|
* <DeviceSelectorPicker> — the operator-facing editor for a v3
|
|
@@ -61087,6 +61282,7 @@ exports.CoverPanel = CoverPanel;
|
|
|
61087
61282
|
exports.CustomFieldRenderersProvider = CustomFieldRenderersProvider;
|
|
61088
61283
|
exports.DEFAULT_COLOR = DEFAULT_COLOR;
|
|
61089
61284
|
exports.DEVICE_COLUMNS = DEVICE_COLUMNS;
|
|
61285
|
+
exports.DEVICE_EXPORT_PAGE_SIZE_KEY = DEVICE_EXPORT_PAGE_SIZE_KEY;
|
|
61090
61286
|
exports.DEVICE_LIST_PAGE_SIZE_KEY = DEVICE_LIST_PAGE_SIZE_KEY;
|
|
61091
61287
|
exports.DEVICE_LIST_PAGE_SIZE_OPTIONS = DEVICE_LIST_PAGE_SIZE_OPTIONS;
|
|
61092
61288
|
exports.DEVICE_PICKER_GROUP_STORAGE_KEY = DEVICE_PICKER_GROUP_STORAGE_KEY;
|
|
@@ -61105,6 +61301,7 @@ exports.DeviceBatchToolbar = DeviceBatchToolbar;
|
|
|
61105
61301
|
exports.DeviceCard = DeviceCard;
|
|
61106
61302
|
exports.DeviceContextProvider = DeviceContextProvider;
|
|
61107
61303
|
exports.DeviceExportPanel = DeviceExportPanel;
|
|
61304
|
+
exports.DeviceExportSetup = DeviceExportSetup;
|
|
61108
61305
|
exports.DeviceFilterBar = DeviceFilterBar;
|
|
61109
61306
|
exports.DeviceGrid = DeviceGrid;
|
|
61110
61307
|
exports.DeviceItem = DeviceItem;
|
|
@@ -61218,6 +61415,7 @@ exports.NotificationTargetsField = NotificationTargetsField;
|
|
|
61218
61415
|
exports.OPTION_SELECT_SEARCH_MIN_OPTIONS = OPTION_SELECT_SEARCH_MIN_OPTIONS;
|
|
61219
61416
|
exports.OfflineBadge = OfflineBadge;
|
|
61220
61417
|
exports.OptionSelect = OptionSelect;
|
|
61418
|
+
exports.PAGE_SIZE_ALL = PAGE_SIZE_ALL;
|
|
61221
61419
|
exports.PHASE_CONFIG = PHASE_CONFIG;
|
|
61222
61420
|
exports.PICKER_CHIP_LIMIT = PICKER_CHIP_LIMIT;
|
|
61223
61421
|
exports.PICKER_DEFAULT_GROUP_BY = PICKER_DEFAULT_GROUP_BY;
|
|
@@ -61232,6 +61430,7 @@ exports.PICKER_WINDOW = PICKER_WINDOW;
|
|
|
61232
61430
|
exports.PRIORITY = PRIORITY;
|
|
61233
61431
|
exports.PTZOverlay = PTZOverlay;
|
|
61234
61432
|
exports.PageHeader = PageHeader;
|
|
61433
|
+
exports.PageSizeSelect = PageSizeSelect;
|
|
61235
61434
|
exports.PhaseIcon = PhaseIcon;
|
|
61236
61435
|
exports.PipelineBuilder = PipelineBuilder;
|
|
61237
61436
|
exports.PipelineRuntimeSelector = PipelineRuntimeSelector;
|
|
@@ -61404,6 +61603,7 @@ exports.deviceTypeMetaOf = deviceTypeMetaOf;
|
|
|
61404
61603
|
exports.devicesToOptions = devicesToOptions;
|
|
61405
61604
|
exports.dockBox = dockBox;
|
|
61406
61605
|
exports.draftFromQuery = draftFromQuery;
|
|
61606
|
+
exports.effectivePageSize = effectivePageSize;
|
|
61407
61607
|
exports.emptyDevicesWidens = emptyDevicesWidens;
|
|
61408
61608
|
exports.emptySessionRun = emptySessionRun;
|
|
61409
61609
|
exports.ensureMfHostInit = ensureMfHostInit;
|
|
@@ -61466,6 +61666,7 @@ exports.optionSelectSearchText = optionSearchText;
|
|
|
61466
61666
|
exports.orphanDeviceLabel = orphanDeviceLabel;
|
|
61467
61667
|
exports.overrideEntityIdFromLink = overrideEntityIdFromLink;
|
|
61468
61668
|
exports.pageRows = pageRows;
|
|
61669
|
+
exports.pageSizeLabel = pageSizeLabel;
|
|
61469
61670
|
exports.parentDetailOf = parentDetailOf;
|
|
61470
61671
|
exports.parseIceCandidate = parseIceCandidate;
|
|
61471
61672
|
exports.parsePickerGroupBy = parsePickerGroupBy;
|
|
@@ -62176,6 +62377,7 @@ exports.useOsdManagerSetSlotBinding = useOsdManagerSetSlotBinding;
|
|
|
62176
62377
|
exports.useOsdManagerUpsertTemplate = useOsdManagerUpsertTemplate;
|
|
62177
62378
|
exports.useOsdSetOverlay = useOsdSetOverlay;
|
|
62178
62379
|
exports.usePTZ = usePTZ;
|
|
62380
|
+
exports.usePersistedPageSize = usePersistedPageSize;
|
|
62179
62381
|
exports.usePetFeederCallPet = usePetFeederCallPet;
|
|
62180
62382
|
exports.usePetFeederCancelFeed = usePetFeederCancelFeed;
|
|
62181
62383
|
exports.usePetFeederFeed = usePetFeederFeed;
|
|
@@ -62253,12 +62455,14 @@ exports.usePipelineAnalyticsResumeForStorageMigration = usePipelineAnalyticsResu
|
|
|
62253
62455
|
exports.usePipelineAnalyticsSaveRetrainAnnotations = usePipelineAnalyticsSaveRetrainAnnotations;
|
|
62254
62456
|
exports.usePipelineAnalyticsSearchObjectEvents = usePipelineAnalyticsSearchObjectEvents;
|
|
62255
62457
|
exports.usePipelineAnalyticsSelectRetrainFrames = usePipelineAnalyticsSelectRetrainFrames;
|
|
62458
|
+
exports.usePipelineAnalyticsSetRetrainFrameComplete = usePipelineAnalyticsSetRetrainFrameComplete;
|
|
62256
62459
|
exports.usePipelineAnalyticsSetTrackFlags = usePipelineAnalyticsSetTrackFlags;
|
|
62257
62460
|
exports.usePipelineAnalyticsSetTrackPurity = usePipelineAnalyticsSetTrackPurity;
|
|
62258
62461
|
exports.usePipelineAnalyticsSetTrackRelation = usePipelineAnalyticsSetTrackRelation;
|
|
62259
62462
|
exports.usePipelineAnalyticsStartStorageMigrationMove = usePipelineAnalyticsStartStorageMigrationMove;
|
|
62260
62463
|
exports.usePipelineAnalyticsWipeAllAnalytics = usePipelineAnalyticsWipeAllAnalytics;
|
|
62261
62464
|
exports.usePipelineAnalyticsWipeObjectEmbeddings = usePipelineAnalyticsWipeObjectEmbeddings;
|
|
62465
|
+
exports.usePipelineAnalyticsWriteRetrainArchive = usePipelineAnalyticsWriteRetrainArchive;
|
|
62262
62466
|
exports.usePipelineExecutorCacheFrameInPool = usePipelineExecutorCacheFrameInPool;
|
|
62263
62467
|
exports.usePipelineExecutorClearDeviceOverrides = usePipelineExecutorClearDeviceOverrides;
|
|
62264
62468
|
exports.usePipelineExecutorClearModelBoundDeviceOverrides = usePipelineExecutorClearModelBoundDeviceOverrides;
|
|
@@ -62640,8 +62844,11 @@ exports.useUserManagementCreateScopedToken = useUserManagementCreateScopedToken;
|
|
|
62640
62844
|
exports.useUserManagementCreateUser = useUserManagementCreateUser;
|
|
62641
62845
|
exports.useUserManagementDeleteUser = useUserManagementDeleteUser;
|
|
62642
62846
|
exports.useUserManagementDisableTotp = useUserManagementDisableTotp;
|
|
62847
|
+
exports.useUserManagementFindUserByExternalIdentity = useUserManagementFindUserByExternalIdentity;
|
|
62643
62848
|
exports.useUserManagementGetTotpStatus = useUserManagementGetTotpStatus;
|
|
62849
|
+
exports.useUserManagementLinkExternalIdentity = useUserManagementLinkExternalIdentity;
|
|
62644
62850
|
exports.useUserManagementListApiKeys = useUserManagementListApiKeys;
|
|
62851
|
+
exports.useUserManagementListExternalIdentities = useUserManagementListExternalIdentities;
|
|
62645
62852
|
exports.useUserManagementListOauthSessions = useUserManagementListOauthSessions;
|
|
62646
62853
|
exports.useUserManagementListScopedTokens = useUserManagementListScopedTokens;
|
|
62647
62854
|
exports.useUserManagementListUsers = useUserManagementListUsers;
|
|
@@ -62655,6 +62862,7 @@ exports.useUserManagementRevokeOauthSession = useUserManagementRevokeOauthSessio
|
|
|
62655
62862
|
exports.useUserManagementRevokeScopedToken = useUserManagementRevokeScopedToken;
|
|
62656
62863
|
exports.useUserManagementSetUserScopes = useUserManagementSetUserScopes;
|
|
62657
62864
|
exports.useUserManagementSetupTotp = useUserManagementSetupTotp;
|
|
62865
|
+
exports.useUserManagementUnlinkExternalIdentity = useUserManagementUnlinkExternalIdentity;
|
|
62658
62866
|
exports.useUserManagementUpdateUser = useUserManagementUpdateUser;
|
|
62659
62867
|
exports.useUserManagementValidateApiKey = useUserManagementValidateApiKey;
|
|
62660
62868
|
exports.useUserManagementValidateCredentials = useUserManagementValidateCredentials;
|