@camstack/ui-library 1.2.247 → 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 +14 -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 +1122 -911
- package/dist/index.js +1591 -1394
- 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,903 @@ 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;
|
|
7364
|
+
/** Generated alias around `trpc.audioAnalyzer.isReady.useQuery`. */
|
|
7365
|
+
var useAudioAnalyzerIsReady = trpc.audioAnalyzer.isReady.useQuery;
|
|
6614
7366
|
/** Generated alias around `trpc.audioAnalyzer.dispose.useMutation`. */
|
|
6615
7367
|
var useAudioAnalyzerDispose = trpc.audioAnalyzer.dispose.useMutation;
|
|
6616
7368
|
/** Generated alias around `trpc.audioAnalyzer.reprobeAudioEngine.useMutation`. */
|
|
@@ -7801,6 +8553,10 @@ var usePipelineAnalyticsCompleteRetrainTrack = trpc.pipelineAnalytics.completeRe
|
|
|
7801
8553
|
var usePipelineAnalyticsRestageRetrainTrack = trpc.pipelineAnalytics.restageRetrainTrack.useMutation;
|
|
7802
8554
|
/** Generated alias around `trpc.pipelineAnalytics.getRetrainExportUrl.useQuery`. */
|
|
7803
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;
|
|
7804
8560
|
/** Generated alias around `trpc.pipelineAnalytics.getEventMedia.useQuery`. */
|
|
7805
8561
|
var usePipelineAnalyticsGetEventMedia = trpc.pipelineAnalytics.getEventMedia.useQuery;
|
|
7806
8562
|
/** Generated alias around `trpc.pipelineAnalytics.getTrackMedia.useQuery`. */
|
|
@@ -8589,6 +9345,14 @@ var useUserManagementOauthExchangeCode = trpc.userManagement.oauthExchangeCode.u
|
|
|
8589
9345
|
var useUserManagementOauthRefresh = trpc.userManagement.oauthRefresh.useMutation;
|
|
8590
9346
|
/** Generated alias around `trpc.userManagement.oauthVerifyAccessToken.useQuery`. */
|
|
8591
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;
|
|
8592
9356
|
/** Generated alias around `trpc.userManagement.listOauthSessions.useQuery`. */
|
|
8593
9357
|
var useUserManagementListOauthSessions = trpc.userManagement.listOauthSessions.useQuery;
|
|
8594
9358
|
/** Generated alias around `trpc.userManagement.revokeOauthSession.useMutation`. */
|
|
@@ -13981,7 +14745,7 @@ function DialogSurface({ state, onClose }) {
|
|
|
13981
14745
|
setError(null);
|
|
13982
14746
|
}
|
|
13983
14747
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
13984
|
-
className: "mt-2 text-xs text-foreground-subtle leading-relaxed",
|
|
14748
|
+
className: "mt-2 text-xs text-foreground-subtle leading-relaxed whitespace-pre-line",
|
|
13985
14749
|
children: state.options.message
|
|
13986
14750
|
});
|
|
13987
14751
|
const footer = state.kind === "alert" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -27164,6 +27928,23 @@ function ColorField({ field, value, onChange, disabled, translationFn }) {
|
|
|
27164
27928
|
})]
|
|
27165
27929
|
});
|
|
27166
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
|
+
}
|
|
27167
27948
|
function ProbeField({ field, value, onChange, disabled, translationFn, onTestField, onAction, externalProbe }) {
|
|
27168
27949
|
const [localStatus, setLocalStatus] = (0, react$1.useState)("idle");
|
|
27169
27950
|
const [localResult, setLocalResult] = (0, react$1.useState)(null);
|
|
@@ -27798,8 +28579,16 @@ function AddonActionButtonField({ field, values, disabled, onAction }) {
|
|
|
27798
28579
|
const [loading, setLoading] = (0, react$1.useState)(false);
|
|
27799
28580
|
const [status, setStatus] = (0, react$1.useState)(null);
|
|
27800
28581
|
const confirm = useConfirm();
|
|
28582
|
+
const prompt = usePrompt();
|
|
27801
28583
|
const deviceId = useDeviceId();
|
|
27802
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;
|
|
27803
28592
|
if (field.confirmMessage) {
|
|
27804
28593
|
if (!await confirm({
|
|
27805
28594
|
title: field.label,
|
|
@@ -27810,6 +28599,7 @@ function AddonActionButtonField({ field, values, disabled, onAction }) {
|
|
|
27810
28599
|
}
|
|
27811
28600
|
if (!onAction) return;
|
|
27812
28601
|
const params = resolveActionParams(field, values);
|
|
28602
|
+
if (field.prompt && asked !== null) params[field.prompt.param] = asked;
|
|
27813
28603
|
if (field.includeDeviceId === true && deviceId !== null && deviceId !== void 0) params["deviceId"] = deviceId;
|
|
27814
28604
|
setLoading(true);
|
|
27815
28605
|
setStatus(null);
|
|
@@ -28270,6 +29060,13 @@ function FormField({ field, values, onChange, disabled, translationFn, onTestFie
|
|
|
28270
29060
|
disabled,
|
|
28271
29061
|
translationFn
|
|
28272
29062
|
});
|
|
29063
|
+
case "icon": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconField, {
|
|
29064
|
+
field,
|
|
29065
|
+
value,
|
|
29066
|
+
onChange: handleChange,
|
|
29067
|
+
disabled,
|
|
29068
|
+
translationFn
|
|
29069
|
+
});
|
|
28273
29070
|
case "node-select": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectField, {
|
|
28274
29071
|
field,
|
|
28275
29072
|
value,
|
|
@@ -49744,7 +50541,7 @@ var CONTROL_FILLS = {
|
|
|
49744
50541
|
[_camstack_types.DeviceType.Image]: false,
|
|
49745
50542
|
[_camstack_types.DeviceType.PetFeeder]: false
|
|
49746
50543
|
};
|
|
49747
|
-
var DEVICE_TYPE_VALUES
|
|
50544
|
+
var DEVICE_TYPE_VALUES = new Set(Object.values(_camstack_types.DeviceType));
|
|
49748
50545
|
/**
|
|
49749
50546
|
* Runtime-string-safe lookup: a device row's `type` crosses the wire as a plain
|
|
49750
50547
|
* string. The type→control-kind DECISION is single-sourced in `@camstack/types`
|
|
@@ -49770,7 +50567,7 @@ function resolveDeviceControl(type) {
|
|
|
49770
50567
|
*/
|
|
49771
50568
|
function resolveControlAlign(type, placement) {
|
|
49772
50569
|
if (placement === "table") return "fit";
|
|
49773
|
-
return DEVICE_TYPE_VALUES
|
|
50570
|
+
return DEVICE_TYPE_VALUES.has(type) && CONTROL_FILLS[type] ? FILL : placement === "center" ? CENTER : RIGHT;
|
|
49774
50571
|
}
|
|
49775
50572
|
//#endregion
|
|
49776
50573
|
//#region src/lib/format-last-seen.ts
|
|
@@ -50098,571 +50895,6 @@ function DeviceBatchActionsBar(props) {
|
|
|
50098
50895
|
})] });
|
|
50099
50896
|
}
|
|
50100
50897
|
//#endregion
|
|
50101
|
-
//#region src/composites/device-meta.ts
|
|
50102
|
-
var DEVICE_TYPE_META = {
|
|
50103
|
-
[_camstack_types.DeviceType.Camera]: {
|
|
50104
|
-
icon: Camera,
|
|
50105
|
-
label: "Camera"
|
|
50106
|
-
},
|
|
50107
|
-
[_camstack_types.DeviceType.Hub]: {
|
|
50108
|
-
icon: Network,
|
|
50109
|
-
label: "Hub"
|
|
50110
|
-
},
|
|
50111
|
-
[_camstack_types.DeviceType.Light]: {
|
|
50112
|
-
icon: Lightbulb,
|
|
50113
|
-
label: "Light"
|
|
50114
|
-
},
|
|
50115
|
-
[_camstack_types.DeviceType.Siren]: {
|
|
50116
|
-
icon: Siren,
|
|
50117
|
-
label: "Siren"
|
|
50118
|
-
},
|
|
50119
|
-
[_camstack_types.DeviceType.Switch]: {
|
|
50120
|
-
icon: ToggleLeft,
|
|
50121
|
-
label: "Switch"
|
|
50122
|
-
},
|
|
50123
|
-
[_camstack_types.DeviceType.Sensor]: {
|
|
50124
|
-
icon: Activity,
|
|
50125
|
-
label: "Sensor"
|
|
50126
|
-
},
|
|
50127
|
-
[_camstack_types.DeviceType.Thermostat]: {
|
|
50128
|
-
icon: Thermometer,
|
|
50129
|
-
label: "Thermostat"
|
|
50130
|
-
},
|
|
50131
|
-
[_camstack_types.DeviceType.Climate]: {
|
|
50132
|
-
icon: AirVent,
|
|
50133
|
-
label: "Air conditioner"
|
|
50134
|
-
},
|
|
50135
|
-
[_camstack_types.DeviceType.Button]: {
|
|
50136
|
-
icon: CircleDot,
|
|
50137
|
-
label: "Button"
|
|
50138
|
-
},
|
|
50139
|
-
[_camstack_types.DeviceType.EventEmitter]: {
|
|
50140
|
-
icon: Zap,
|
|
50141
|
-
label: "Event Emitter"
|
|
50142
|
-
},
|
|
50143
|
-
[_camstack_types.DeviceType.Update]: {
|
|
50144
|
-
icon: RefreshCw,
|
|
50145
|
-
label: "Update"
|
|
50146
|
-
},
|
|
50147
|
-
[_camstack_types.DeviceType.Generic]: {
|
|
50148
|
-
icon: Box,
|
|
50149
|
-
label: "Generic"
|
|
50150
|
-
},
|
|
50151
|
-
[_camstack_types.DeviceType.Notifier]: {
|
|
50152
|
-
icon: Bell,
|
|
50153
|
-
label: "Notifier"
|
|
50154
|
-
},
|
|
50155
|
-
[_camstack_types.DeviceType.Script]: {
|
|
50156
|
-
icon: ScrollText,
|
|
50157
|
-
label: "Script"
|
|
50158
|
-
},
|
|
50159
|
-
[_camstack_types.DeviceType.Automation]: {
|
|
50160
|
-
icon: Workflow,
|
|
50161
|
-
label: "Automation"
|
|
50162
|
-
},
|
|
50163
|
-
[_camstack_types.DeviceType.Lock]: {
|
|
50164
|
-
icon: Lock,
|
|
50165
|
-
label: "Lock"
|
|
50166
|
-
},
|
|
50167
|
-
[_camstack_types.DeviceType.Cover]: {
|
|
50168
|
-
icon: Blinds,
|
|
50169
|
-
label: "Cover"
|
|
50170
|
-
},
|
|
50171
|
-
[_camstack_types.DeviceType.Valve]: {
|
|
50172
|
-
icon: Pipette,
|
|
50173
|
-
label: "Valve"
|
|
50174
|
-
},
|
|
50175
|
-
[_camstack_types.DeviceType.Humidifier]: {
|
|
50176
|
-
icon: Waves,
|
|
50177
|
-
label: "Humidifier"
|
|
50178
|
-
},
|
|
50179
|
-
[_camstack_types.DeviceType.WaterHeater]: {
|
|
50180
|
-
icon: Bath,
|
|
50181
|
-
label: "Water heater"
|
|
50182
|
-
},
|
|
50183
|
-
[_camstack_types.DeviceType.Fan]: {
|
|
50184
|
-
icon: Fan,
|
|
50185
|
-
label: "Fan"
|
|
50186
|
-
},
|
|
50187
|
-
[_camstack_types.DeviceType.MediaPlayer]: {
|
|
50188
|
-
icon: MonitorPlay,
|
|
50189
|
-
label: "Media player"
|
|
50190
|
-
},
|
|
50191
|
-
[_camstack_types.DeviceType.AlarmPanel]: {
|
|
50192
|
-
icon: ShieldAlert,
|
|
50193
|
-
label: "Alarm panel"
|
|
50194
|
-
},
|
|
50195
|
-
[_camstack_types.DeviceType.Control]: {
|
|
50196
|
-
icon: SlidersHorizontal,
|
|
50197
|
-
label: "Control"
|
|
50198
|
-
},
|
|
50199
|
-
[_camstack_types.DeviceType.Presence]: {
|
|
50200
|
-
icon: MapPin,
|
|
50201
|
-
label: "Presence"
|
|
50202
|
-
},
|
|
50203
|
-
[_camstack_types.DeviceType.Weather]: {
|
|
50204
|
-
icon: CloudSun,
|
|
50205
|
-
label: "Weather"
|
|
50206
|
-
},
|
|
50207
|
-
[_camstack_types.DeviceType.Vacuum]: {
|
|
50208
|
-
icon: Bot,
|
|
50209
|
-
label: "Vacuum"
|
|
50210
|
-
},
|
|
50211
|
-
[_camstack_types.DeviceType.LawnMower]: {
|
|
50212
|
-
icon: Tractor,
|
|
50213
|
-
label: "Lawn mower"
|
|
50214
|
-
},
|
|
50215
|
-
[_camstack_types.DeviceType.Container]: {
|
|
50216
|
-
icon: Box,
|
|
50217
|
-
label: "Container"
|
|
50218
|
-
},
|
|
50219
|
-
[_camstack_types.DeviceType.Image]: {
|
|
50220
|
-
icon: Image,
|
|
50221
|
-
label: "Image"
|
|
50222
|
-
},
|
|
50223
|
-
[_camstack_types.DeviceType.PetFeeder]: {
|
|
50224
|
-
icon: Bone,
|
|
50225
|
-
label: "Pet feeder"
|
|
50226
|
-
}
|
|
50227
|
-
};
|
|
50228
|
-
var DEVICE_ROLE_META = {
|
|
50229
|
-
[_camstack_types.DeviceRole.Siren]: {
|
|
50230
|
-
icon: Siren,
|
|
50231
|
-
label: "Siren"
|
|
50232
|
-
},
|
|
50233
|
-
[_camstack_types.DeviceRole.Floodlight]: {
|
|
50234
|
-
icon: Lightbulb,
|
|
50235
|
-
label: "Floodlight"
|
|
50236
|
-
},
|
|
50237
|
-
[_camstack_types.DeviceRole.Spotlight]: {
|
|
50238
|
-
icon: Flashlight,
|
|
50239
|
-
label: "Spotlight"
|
|
50240
|
-
},
|
|
50241
|
-
[_camstack_types.DeviceRole.PirSensor]: {
|
|
50242
|
-
icon: Radar,
|
|
50243
|
-
label: "PIR sensor"
|
|
50244
|
-
},
|
|
50245
|
-
[_camstack_types.DeviceRole.Chime]: {
|
|
50246
|
-
icon: Bell,
|
|
50247
|
-
label: "Chime"
|
|
50248
|
-
},
|
|
50249
|
-
[_camstack_types.DeviceRole.Autotrack]: {
|
|
50250
|
-
icon: Crosshair,
|
|
50251
|
-
label: "Auto-track"
|
|
50252
|
-
},
|
|
50253
|
-
[_camstack_types.DeviceRole.Nightvision]: {
|
|
50254
|
-
icon: Moon,
|
|
50255
|
-
label: "Night vision"
|
|
50256
|
-
},
|
|
50257
|
-
[_camstack_types.DeviceRole.PrivacyMask]: {
|
|
50258
|
-
icon: EyeOff,
|
|
50259
|
-
label: "Privacy mask"
|
|
50260
|
-
},
|
|
50261
|
-
[_camstack_types.DeviceRole.Doorbell]: {
|
|
50262
|
-
icon: DoorClosed,
|
|
50263
|
-
label: "Doorbell"
|
|
50264
|
-
},
|
|
50265
|
-
[_camstack_types.DeviceRole.BinaryHelper]: {
|
|
50266
|
-
icon: ToggleLeft,
|
|
50267
|
-
label: "Binary helper"
|
|
50268
|
-
},
|
|
50269
|
-
[_camstack_types.DeviceRole.MotionSensor]: {
|
|
50270
|
-
icon: Footprints,
|
|
50271
|
-
label: "Motion sensor"
|
|
50272
|
-
},
|
|
50273
|
-
[_camstack_types.DeviceRole.ContactSensor]: {
|
|
50274
|
-
icon: DoorOpen,
|
|
50275
|
-
label: "Contact sensor"
|
|
50276
|
-
},
|
|
50277
|
-
[_camstack_types.DeviceRole.LeakSensor]: {
|
|
50278
|
-
icon: Droplet,
|
|
50279
|
-
label: "Leak sensor"
|
|
50280
|
-
},
|
|
50281
|
-
[_camstack_types.DeviceRole.SmokeSensor]: {
|
|
50282
|
-
icon: AlarmSmoke,
|
|
50283
|
-
label: "Smoke sensor"
|
|
50284
|
-
},
|
|
50285
|
-
[_camstack_types.DeviceRole.COSensor]: {
|
|
50286
|
-
icon: Wind,
|
|
50287
|
-
label: "CO sensor"
|
|
50288
|
-
},
|
|
50289
|
-
[_camstack_types.DeviceRole.GasSensor]: {
|
|
50290
|
-
icon: Flame,
|
|
50291
|
-
label: "Gas sensor"
|
|
50292
|
-
},
|
|
50293
|
-
[_camstack_types.DeviceRole.TamperSensor]: {
|
|
50294
|
-
icon: ShieldAlert,
|
|
50295
|
-
label: "Tamper sensor"
|
|
50296
|
-
},
|
|
50297
|
-
[_camstack_types.DeviceRole.VibrationSensor]: {
|
|
50298
|
-
icon: Vibrate,
|
|
50299
|
-
label: "Vibration sensor"
|
|
50300
|
-
},
|
|
50301
|
-
[_camstack_types.DeviceRole.ConnectivitySensor]: {
|
|
50302
|
-
icon: Wifi,
|
|
50303
|
-
label: "Connectivity"
|
|
50304
|
-
},
|
|
50305
|
-
[_camstack_types.DeviceRole.SoundSensor]: {
|
|
50306
|
-
icon: Volume2,
|
|
50307
|
-
label: "Sound sensor"
|
|
50308
|
-
},
|
|
50309
|
-
[_camstack_types.DeviceRole.BinarySensor]: {
|
|
50310
|
-
icon: ToggleLeft,
|
|
50311
|
-
label: "Binary sensor"
|
|
50312
|
-
},
|
|
50313
|
-
[_camstack_types.DeviceRole.TemperatureSensor]: {
|
|
50314
|
-
icon: Thermometer,
|
|
50315
|
-
label: "Temperature"
|
|
50316
|
-
},
|
|
50317
|
-
[_camstack_types.DeviceRole.HumiditySensor]: {
|
|
50318
|
-
icon: Droplets,
|
|
50319
|
-
label: "Humidity"
|
|
50320
|
-
},
|
|
50321
|
-
[_camstack_types.DeviceRole.AmbientLightSensor]: {
|
|
50322
|
-
icon: Sun,
|
|
50323
|
-
label: "Ambient light"
|
|
50324
|
-
},
|
|
50325
|
-
[_camstack_types.DeviceRole.PressureSensor]: {
|
|
50326
|
-
icon: Gauge,
|
|
50327
|
-
label: "Pressure"
|
|
50328
|
-
},
|
|
50329
|
-
[_camstack_types.DeviceRole.WindSensor]: {
|
|
50330
|
-
icon: Wind,
|
|
50331
|
-
label: "Wind"
|
|
50332
|
-
},
|
|
50333
|
-
[_camstack_types.DeviceRole.RainSensor]: {
|
|
50334
|
-
icon: CloudRain,
|
|
50335
|
-
label: "Rain"
|
|
50336
|
-
},
|
|
50337
|
-
[_camstack_types.DeviceRole.UvSensor]: {
|
|
50338
|
-
icon: SunMedium,
|
|
50339
|
-
label: "UV index"
|
|
50340
|
-
},
|
|
50341
|
-
[_camstack_types.DeviceRole.SolarRadiationSensor]: {
|
|
50342
|
-
icon: Sunrise,
|
|
50343
|
-
label: "Solar radiation"
|
|
50344
|
-
},
|
|
50345
|
-
[_camstack_types.DeviceRole.SoilMoistureSensor]: {
|
|
50346
|
-
icon: Sprout,
|
|
50347
|
-
label: "Soil moisture"
|
|
50348
|
-
},
|
|
50349
|
-
[_camstack_types.DeviceRole.PowerSensor]: {
|
|
50350
|
-
icon: Zap,
|
|
50351
|
-
label: "Power"
|
|
50352
|
-
},
|
|
50353
|
-
[_camstack_types.DeviceRole.EnergySensor]: {
|
|
50354
|
-
icon: Zap,
|
|
50355
|
-
label: "Energy"
|
|
50356
|
-
},
|
|
50357
|
-
[_camstack_types.DeviceRole.VoltageSensor]: {
|
|
50358
|
-
icon: Zap,
|
|
50359
|
-
label: "Voltage"
|
|
50360
|
-
},
|
|
50361
|
-
[_camstack_types.DeviceRole.CurrentSensor]: {
|
|
50362
|
-
icon: Zap,
|
|
50363
|
-
label: "Current"
|
|
50364
|
-
},
|
|
50365
|
-
[_camstack_types.DeviceRole.AirQualitySensor]: {
|
|
50366
|
-
icon: Wind,
|
|
50367
|
-
label: "Air quality"
|
|
50368
|
-
},
|
|
50369
|
-
[_camstack_types.DeviceRole.BatterySensor]: {
|
|
50370
|
-
icon: Gauge,
|
|
50371
|
-
label: "Battery"
|
|
50372
|
-
},
|
|
50373
|
-
[_camstack_types.DeviceRole.NumericSensor]: {
|
|
50374
|
-
icon: Hash,
|
|
50375
|
-
label: "Numeric sensor"
|
|
50376
|
-
},
|
|
50377
|
-
[_camstack_types.DeviceRole.EnumSensor]: {
|
|
50378
|
-
icon: List,
|
|
50379
|
-
label: "Enum sensor"
|
|
50380
|
-
},
|
|
50381
|
-
[_camstack_types.DeviceRole.DateTimeSensor]: {
|
|
50382
|
-
icon: Clock,
|
|
50383
|
-
label: "Date / time"
|
|
50384
|
-
},
|
|
50385
|
-
[_camstack_types.DeviceRole.GenericSensor]: {
|
|
50386
|
-
icon: Gauge,
|
|
50387
|
-
label: "Sensor"
|
|
50388
|
-
},
|
|
50389
|
-
[_camstack_types.DeviceRole.NumericControl]: {
|
|
50390
|
-
icon: SlidersHorizontal,
|
|
50391
|
-
label: "Numeric control"
|
|
50392
|
-
},
|
|
50393
|
-
[_camstack_types.DeviceRole.SelectControl]: {
|
|
50394
|
-
icon: ListChecks,
|
|
50395
|
-
label: "Select control"
|
|
50396
|
-
},
|
|
50397
|
-
[_camstack_types.DeviceRole.TextControl]: {
|
|
50398
|
-
icon: Type,
|
|
50399
|
-
label: "Text control"
|
|
50400
|
-
},
|
|
50401
|
-
[_camstack_types.DeviceRole.DateTimeControl]: {
|
|
50402
|
-
icon: Clock,
|
|
50403
|
-
label: "Date / time control"
|
|
50404
|
-
},
|
|
50405
|
-
[_camstack_types.DeviceRole.MobilePushNotifier]: {
|
|
50406
|
-
icon: Smartphone,
|
|
50407
|
-
label: "Mobile push"
|
|
50408
|
-
},
|
|
50409
|
-
[_camstack_types.DeviceRole.MessagingNotifier]: {
|
|
50410
|
-
icon: MessageSquare,
|
|
50411
|
-
label: "Messaging"
|
|
50412
|
-
},
|
|
50413
|
-
[_camstack_types.DeviceRole.EmailNotifier]: {
|
|
50414
|
-
icon: Mail,
|
|
50415
|
-
label: "Email"
|
|
50416
|
-
},
|
|
50417
|
-
[_camstack_types.DeviceRole.GenericNotifier]: {
|
|
50418
|
-
icon: Bell,
|
|
50419
|
-
label: "Notifier"
|
|
50420
|
-
}
|
|
50421
|
-
};
|
|
50422
|
-
var DEVICE_TYPE_VALUES = new Set(Object.values(_camstack_types.DeviceType));
|
|
50423
|
-
var DEVICE_ROLE_VALUES = new Set(Object.values(_camstack_types.DeviceRole));
|
|
50424
|
-
function isDeviceType(value) {
|
|
50425
|
-
return DEVICE_TYPE_VALUES.has(value);
|
|
50426
|
-
}
|
|
50427
|
-
function isDeviceRole(value) {
|
|
50428
|
-
return DEVICE_ROLE_VALUES.has(value);
|
|
50429
|
-
}
|
|
50430
|
-
/** Meta for a known `DeviceType`. */
|
|
50431
|
-
function deviceTypeMeta(type) {
|
|
50432
|
-
return DEVICE_TYPE_META[type];
|
|
50433
|
-
}
|
|
50434
|
-
/** Meta for a known `DeviceRole`. */
|
|
50435
|
-
function deviceRoleMeta(role) {
|
|
50436
|
-
return DEVICE_ROLE_META[role];
|
|
50437
|
-
}
|
|
50438
|
-
var FALLBACK_DEVICE_TYPE_META = DEVICE_TYPE_META[_camstack_types.DeviceType.Generic];
|
|
50439
|
-
var FALLBACK_DEVICE_ROLE_META = DEVICE_ROLE_META[_camstack_types.DeviceRole.GenericSensor];
|
|
50440
|
-
/**
|
|
50441
|
-
* Runtime-string-safe lookup: device data crosses process / network boundaries
|
|
50442
|
-
* as plain strings, so an unrecognised value falls back to the `Generic` meta
|
|
50443
|
-
* instead of throwing.
|
|
50444
|
-
*
|
|
50445
|
-
* This also guards mixed-version module-federation loads where the host
|
|
50446
|
-
* `@camstack/types` enum has a new member before the loaded ui-library bundle
|
|
50447
|
-
* has the matching `DEVICE_TYPE_META` entry.
|
|
50448
|
-
*/
|
|
50449
|
-
function deviceTypeMetaOf(type) {
|
|
50450
|
-
if (!isDeviceType(type)) return FALLBACK_DEVICE_TYPE_META;
|
|
50451
|
-
return DEVICE_TYPE_META[type] ?? FALLBACK_DEVICE_TYPE_META;
|
|
50452
|
-
}
|
|
50453
|
-
/** Runtime-string-safe role lookup; unknown roles fall back to `GenericSensor`. */
|
|
50454
|
-
function deviceRoleMetaOf(role) {
|
|
50455
|
-
if (!isDeviceRole(role)) return FALLBACK_DEVICE_ROLE_META;
|
|
50456
|
-
return DEVICE_ROLE_META[role] ?? FALLBACK_DEVICE_ROLE_META;
|
|
50457
|
-
}
|
|
50458
|
-
/**
|
|
50459
|
-
* Icons an operator may pick for a per-device `display.icon` override (and for
|
|
50460
|
-
* a per-role default), keyed by a stable kebab-case name. Named imports only —
|
|
50461
|
-
* no dynamic indexing into lucide, so the bundle carries exactly this set.
|
|
50462
|
-
* Unknown keys resolve to `undefined` (caller falls through to the next level).
|
|
50463
|
-
*
|
|
50464
|
-
* The vocabulary is the one the VIEWER draws from too (its own icon module,
|
|
50465
|
-
* keyed by these same strings): a key added here that the phone cannot draw
|
|
50466
|
-
* falls through to the next resolution level there, which reads as "my change
|
|
50467
|
-
* did nothing". So the KEY is the contract — a stable kebab-case string, never
|
|
50468
|
-
* a glyph identity — and `device-meta.test.ts` pins that every key resolves
|
|
50469
|
-
* and that the set never loses a key an operator may already have persisted.
|
|
50470
|
-
*
|
|
50471
|
-
* Grouped by what an operator is naming: a device, a light or appliance, a
|
|
50472
|
-
* sensor or the weather it reads, a room, or what moves through it. `gauge2`
|
|
50473
|
-
* is a legacy alias kept for rows that persisted it.
|
|
50474
|
-
*/
|
|
50475
|
-
var DISPLAY_ICON_REGISTRY = {
|
|
50476
|
-
camera: Camera,
|
|
50477
|
-
network: Network,
|
|
50478
|
-
"toggle-left": ToggleLeft,
|
|
50479
|
-
"toggle-right": ToggleRight,
|
|
50480
|
-
"circle-dot": CircleDot,
|
|
50481
|
-
"refresh-cw": RefreshCw,
|
|
50482
|
-
box: Box,
|
|
50483
|
-
"scroll-text": ScrollText,
|
|
50484
|
-
workflow: Workflow,
|
|
50485
|
-
lock: Lock,
|
|
50486
|
-
"lock-open": LockOpen,
|
|
50487
|
-
blinds: Blinds,
|
|
50488
|
-
"air-vent": AirVent,
|
|
50489
|
-
"monitor-play": MonitorPlay,
|
|
50490
|
-
"sliders-horizontal": SlidersHorizontal,
|
|
50491
|
-
"map-pin": MapPin,
|
|
50492
|
-
bot: Bot,
|
|
50493
|
-
tractor: Tractor,
|
|
50494
|
-
image: Image,
|
|
50495
|
-
bone: Bone,
|
|
50496
|
-
"door-closed": DoorClosed,
|
|
50497
|
-
"door-open": DoorOpen,
|
|
50498
|
-
crosshair: Crosshair,
|
|
50499
|
-
eye: Eye,
|
|
50500
|
-
"eye-off": EyeOff,
|
|
50501
|
-
smartphone: Smartphone,
|
|
50502
|
-
phone: Phone,
|
|
50503
|
-
tablet: Tablet,
|
|
50504
|
-
laptop: Laptop,
|
|
50505
|
-
monitor: Monitor,
|
|
50506
|
-
tv: Tv,
|
|
50507
|
-
speaker: Speaker,
|
|
50508
|
-
printer: Printer,
|
|
50509
|
-
projector: Projector,
|
|
50510
|
-
"gamepad-2": Gamepad2,
|
|
50511
|
-
radio: Radio,
|
|
50512
|
-
router: Router,
|
|
50513
|
-
bluetooth: Bluetooth,
|
|
50514
|
-
cpu: Cpu,
|
|
50515
|
-
"hard-drive": HardDrive,
|
|
50516
|
-
server: Server,
|
|
50517
|
-
mic: Mic,
|
|
50518
|
-
"mic-off": MicOff,
|
|
50519
|
-
video: Video,
|
|
50520
|
-
"video-off": VideoOff,
|
|
50521
|
-
music: Music,
|
|
50522
|
-
plug: Plug,
|
|
50523
|
-
"plug-zap": PlugZap,
|
|
50524
|
-
power: Power,
|
|
50525
|
-
"power-off": PowerOff,
|
|
50526
|
-
cable: Cable,
|
|
50527
|
-
battery: Battery,
|
|
50528
|
-
"battery-charging": BatteryCharging,
|
|
50529
|
-
"battery-full": BatteryFull,
|
|
50530
|
-
"battery-low": BatteryLow,
|
|
50531
|
-
key: Key,
|
|
50532
|
-
"key-round": KeyRound,
|
|
50533
|
-
mailbox: Mailbox,
|
|
50534
|
-
package: Package,
|
|
50535
|
-
shield: Shield,
|
|
50536
|
-
"shield-check": ShieldCheck,
|
|
50537
|
-
"shield-off": ShieldOff,
|
|
50538
|
-
lightbulb: Lightbulb,
|
|
50539
|
-
lamp: Lamp,
|
|
50540
|
-
"lamp-ceiling": LampCeiling,
|
|
50541
|
-
"lamp-desk": LampDesk,
|
|
50542
|
-
"lamp-floor": LampFloor,
|
|
50543
|
-
flashlight: Flashlight,
|
|
50544
|
-
heater: Heater,
|
|
50545
|
-
snowflake: Snowflake,
|
|
50546
|
-
"thermometer-sun": ThermometerSun,
|
|
50547
|
-
"thermometer-snowflake": ThermometerSnowflake,
|
|
50548
|
-
refrigerator: Refrigerator,
|
|
50549
|
-
microwave: Microwave,
|
|
50550
|
-
"washing-machine": WashingMachine,
|
|
50551
|
-
"cooking-pot": CookingPot,
|
|
50552
|
-
utensils: Utensils,
|
|
50553
|
-
thermometer: Thermometer,
|
|
50554
|
-
droplets: Droplets,
|
|
50555
|
-
droplet: Droplet,
|
|
50556
|
-
gauge: Gauge,
|
|
50557
|
-
gauge2: Gauge,
|
|
50558
|
-
sun: Sun,
|
|
50559
|
-
"sun-medium": SunMedium,
|
|
50560
|
-
sunrise: Sunrise,
|
|
50561
|
-
moon: Moon,
|
|
50562
|
-
wind: Wind,
|
|
50563
|
-
cloud: Cloud,
|
|
50564
|
-
"cloud-rain": CloudRain,
|
|
50565
|
-
"cloud-sun": CloudSun,
|
|
50566
|
-
waves: Waves,
|
|
50567
|
-
sprout: Sprout,
|
|
50568
|
-
leaf: Leaf,
|
|
50569
|
-
flower: Flower,
|
|
50570
|
-
zap: Zap,
|
|
50571
|
-
flame: Flame,
|
|
50572
|
-
bell: Bell,
|
|
50573
|
-
"bell-ring": BellRing,
|
|
50574
|
-
"bell-off": BellOff,
|
|
50575
|
-
siren: Siren,
|
|
50576
|
-
radar: Radar,
|
|
50577
|
-
activity: Activity,
|
|
50578
|
-
hash: Hash,
|
|
50579
|
-
clock: Clock,
|
|
50580
|
-
timer: Timer,
|
|
50581
|
-
calendar: Calendar,
|
|
50582
|
-
pipette: Pipette,
|
|
50583
|
-
fan: Fan,
|
|
50584
|
-
bath: Bath,
|
|
50585
|
-
footprints: Footprints,
|
|
50586
|
-
"alarm-smoke": AlarmSmoke,
|
|
50587
|
-
"shield-alert": ShieldAlert,
|
|
50588
|
-
vibrate: Vibrate,
|
|
50589
|
-
wifi: Wifi,
|
|
50590
|
-
"wifi-off": WifiOff,
|
|
50591
|
-
"volume-2": Volume2,
|
|
50592
|
-
"volume-x": VolumeX,
|
|
50593
|
-
heart: Heart,
|
|
50594
|
-
"heart-pulse": HeartPulse,
|
|
50595
|
-
star: Star,
|
|
50596
|
-
sparkles: Sparkles,
|
|
50597
|
-
house: House,
|
|
50598
|
-
sofa: Sofa,
|
|
50599
|
-
"bed-double": BedDouble,
|
|
50600
|
-
bed: Bed,
|
|
50601
|
-
warehouse: Warehouse,
|
|
50602
|
-
trees: Trees,
|
|
50603
|
-
"tree-pine": TreePine,
|
|
50604
|
-
fence: Fence,
|
|
50605
|
-
store: Store,
|
|
50606
|
-
building: Building,
|
|
50607
|
-
"building-2": Building2,
|
|
50608
|
-
mountain: Mountain,
|
|
50609
|
-
umbrella: Umbrella,
|
|
50610
|
-
dumbbell: Dumbbell,
|
|
50611
|
-
wrench: Wrench,
|
|
50612
|
-
hammer: Hammer,
|
|
50613
|
-
drill: Drill,
|
|
50614
|
-
"waves-ladder": WavesLadder,
|
|
50615
|
-
"circle-parking": CircleParking,
|
|
50616
|
-
briefcase: Briefcase,
|
|
50617
|
-
route: Route,
|
|
50618
|
-
car: Car,
|
|
50619
|
-
bike: Bike,
|
|
50620
|
-
bus: Bus,
|
|
50621
|
-
truck: Truck,
|
|
50622
|
-
plane: Plane,
|
|
50623
|
-
"train-front": TrainFront,
|
|
50624
|
-
sailboat: Sailboat,
|
|
50625
|
-
dog: Dog,
|
|
50626
|
-
cat: Cat,
|
|
50627
|
-
bird: Bird,
|
|
50628
|
-
"paw-print": PawPrint,
|
|
50629
|
-
baby: Baby,
|
|
50630
|
-
user: User,
|
|
50631
|
-
users: Users,
|
|
50632
|
-
"person-standing": PersonStanding
|
|
50633
|
-
};
|
|
50634
|
-
/** Resolve a `display.icon` name to a lucide component, or `undefined` when the
|
|
50635
|
-
* name is not in the curated `DISPLAY_ICON_REGISTRY`. */
|
|
50636
|
-
function resolveDisplayIcon(name) {
|
|
50637
|
-
return Object.hasOwn(DISPLAY_ICON_REGISTRY, name) ? DISPLAY_ICON_REGISTRY[name] : void 0;
|
|
50638
|
-
}
|
|
50639
|
-
/**
|
|
50640
|
-
* EXHAUSTIVE device-type filter options — one entry per `DeviceType` member,
|
|
50641
|
-
* derived from `DEVICE_TYPE_META` so the set is always complete and a newly
|
|
50642
|
-
* added `DeviceType` automatically appears in every type filter (Devices page,
|
|
50643
|
-
* adoption modal, …) without touching any consumer.
|
|
50644
|
-
*
|
|
50645
|
-
* The previous per-consumer logic built options from the types PRESENT in the
|
|
50646
|
-
* list (or a hand-maintained subset), so recently-added types (vacuum, lawn
|
|
50647
|
-
* mower, valve, humidifier, water heater, weather, image, …) were silently
|
|
50648
|
-
* missing from the dropdown. This is the single source of truth instead.
|
|
50649
|
-
*
|
|
50650
|
-
* `id` is the raw `DeviceType` string (matches the filtering predicate, which
|
|
50651
|
-
* compares against `device.type`); `label` + `icon` come from the meta map.
|
|
50652
|
-
* Ordered by `DeviceType` declaration order for a stable, intentional layout.
|
|
50653
|
-
*/
|
|
50654
|
-
var ALL_DEVICE_TYPE_FILTER_OPTIONS = Object.values(_camstack_types.DeviceType).map((type) => {
|
|
50655
|
-
const meta = deviceTypeMetaOf(type);
|
|
50656
|
-
return {
|
|
50657
|
-
id: type,
|
|
50658
|
-
label: meta.label,
|
|
50659
|
-
icon: meta.icon
|
|
50660
|
-
};
|
|
50661
|
-
});
|
|
50662
|
-
function allDeviceTypeFilterOptions() {
|
|
50663
|
-
return ALL_DEVICE_TYPE_FILTER_OPTIONS;
|
|
50664
|
-
}
|
|
50665
|
-
//#endregion
|
|
50666
50898
|
//#region src/hooks/use-debounced-string.ts
|
|
50667
50899
|
/**
|
|
50668
50900
|
* useDebouncedString — return `value` after `delay` ms have passed
|
|
@@ -50681,6 +50913,59 @@ function useDebouncedString(value, delayMs) {
|
|
|
50681
50913
|
return debounced;
|
|
50682
50914
|
}
|
|
50683
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
|
|
50684
50969
|
//#region src/hooks/use-device-list-page-size.ts
|
|
50685
50970
|
/**
|
|
50686
50971
|
* useDeviceListPageSize — global page-size preference for the device-list
|
|
@@ -50691,8 +50976,9 @@ function useDebouncedString(value, delayMs) {
|
|
|
50691
50976
|
* value is validated against {@link DEVICE_LIST_PAGE_SIZE_OPTIONS}; any
|
|
50692
50977
|
* garbage / out-of-range value falls back to the provided default.
|
|
50693
50978
|
*
|
|
50694
|
-
*
|
|
50695
|
-
* 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.
|
|
50696
50982
|
*/
|
|
50697
50983
|
/** Selectable per-page sizes. The table default (50) is intentionally one of them. */
|
|
50698
50984
|
var DEVICE_LIST_PAGE_SIZE_OPTIONS = [
|
|
@@ -50703,33 +50989,6 @@ var DEVICE_LIST_PAGE_SIZE_OPTIONS = [
|
|
|
50703
50989
|
];
|
|
50704
50990
|
/** Single global key shared across every device-list surface. */
|
|
50705
50991
|
var DEVICE_LIST_PAGE_SIZE_KEY = "camstack.device-list.pageSize";
|
|
50706
|
-
function isAllowed(value) {
|
|
50707
|
-
return DEVICE_LIST_PAGE_SIZE_OPTIONS.includes(value);
|
|
50708
|
-
}
|
|
50709
|
-
/**
|
|
50710
|
-
* Normalize a caller-supplied `defaultSize` to an allowed option, falling back
|
|
50711
|
-
* to the canonical default so a stray value can never seed a phantom size.
|
|
50712
|
-
*/
|
|
50713
|
-
function safeDefault(defaultSize) {
|
|
50714
|
-
return isAllowed(defaultSize) ? defaultSize : 50;
|
|
50715
|
-
}
|
|
50716
|
-
function readStored(defaultSize) {
|
|
50717
|
-
if (typeof window === "undefined") return defaultSize;
|
|
50718
|
-
try {
|
|
50719
|
-
const raw = window.localStorage.getItem(DEVICE_LIST_PAGE_SIZE_KEY);
|
|
50720
|
-
if (raw === null) return defaultSize;
|
|
50721
|
-
const parsed = Number.parseInt(raw, 10);
|
|
50722
|
-
return Number.isFinite(parsed) && isAllowed(parsed) ? parsed : defaultSize;
|
|
50723
|
-
} catch {
|
|
50724
|
-
return defaultSize;
|
|
50725
|
-
}
|
|
50726
|
-
}
|
|
50727
|
-
function writeStored(value) {
|
|
50728
|
-
if (typeof window === "undefined") return;
|
|
50729
|
-
try {
|
|
50730
|
-
window.localStorage.setItem(DEVICE_LIST_PAGE_SIZE_KEY, String(value));
|
|
50731
|
-
} catch {}
|
|
50732
|
-
}
|
|
50733
50992
|
/**
|
|
50734
50993
|
* @param defaultSize fallback when nothing valid is stored. If it is not itself
|
|
50735
50994
|
* a member of {@link DEVICE_LIST_PAGE_SIZE_OPTIONS}, it is replaced by
|
|
@@ -50737,13 +50996,11 @@ function writeStored(value) {
|
|
|
50737
50996
|
* @returns `[size, setSize]` — `setSize` ignores values outside the allowed set.
|
|
50738
50997
|
*/
|
|
50739
50998
|
function useDeviceListPageSize(defaultSize) {
|
|
50740
|
-
|
|
50741
|
-
|
|
50742
|
-
|
|
50743
|
-
|
|
50744
|
-
|
|
50745
|
-
writeStored(next);
|
|
50746
|
-
}, [])];
|
|
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
|
+
});
|
|
50747
51004
|
}
|
|
50748
51005
|
//#endregion
|
|
50749
51006
|
//#region src/composites/device-item/helpers.ts
|
|
@@ -53041,6 +53298,29 @@ function groupTopLevelAndAccessories(devices, options) {
|
|
|
53041
53298
|
};
|
|
53042
53299
|
}
|
|
53043
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
|
|
53044
53324
|
//#region src/composites/device-list/multi-select.tsx
|
|
53045
53325
|
/**
|
|
53046
53326
|
* Compact multi-select dropdown — a single chip-sized trigger ("Label · N")
|
|
@@ -53955,23 +54235,11 @@ function DeviceModeList(props) {
|
|
|
53955
54235
|
totalItems,
|
|
53956
54236
|
" ",
|
|
53957
54237
|
totalItems === 1 ? "device" : "devices"
|
|
53958
|
-
] }), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
53959
|
-
|
|
53960
|
-
|
|
53961
|
-
|
|
53962
|
-
|
|
53963
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
53964
|
-
"aria-label": "Devices per page",
|
|
53965
|
-
value: tablePageSize,
|
|
53966
|
-
onChange: (e) => {
|
|
53967
|
-
setTablePageSize(Number.parseInt(e.target.value, 10));
|
|
53968
|
-
},
|
|
53969
|
-
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",
|
|
53970
|
-
children: DEVICE_LIST_PAGE_SIZE_OPTIONS.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
53971
|
-
value: opt,
|
|
53972
|
-
children: opt
|
|
53973
|
-
}, opt))
|
|
53974
|
-
})]
|
|
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
|
|
53975
54243
|
})]
|
|
53976
54244
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pagination, {
|
|
53977
54245
|
currentPage: safePage,
|
|
@@ -54015,6 +54283,7 @@ function useDeviceListRealtimeSync() {
|
|
|
54015
54283
|
}
|
|
54016
54284
|
//#endregion
|
|
54017
54285
|
//#region src/composites/device-list/generic-mode.tsx
|
|
54286
|
+
var FIXED_PAGE_SIZE = 100;
|
|
54018
54287
|
/**
|
|
54019
54288
|
* Generic render-prop list: search + pagination chrome shared with the device
|
|
54020
54289
|
* list, over an arbitrary item type. Local (non-URL) state — intended for
|
|
@@ -54022,7 +54291,12 @@ function useDeviceListRealtimeSync() {
|
|
|
54022
54291
|
* `renderItem`.
|
|
54023
54292
|
*/
|
|
54024
54293
|
function GenericModeList(props) {
|
|
54025
|
-
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
|
+
});
|
|
54026
54300
|
const [searchInput, setSearchInput] = (0, react$1.useState)("");
|
|
54027
54301
|
const debouncedSearch = useDebouncedString(searchInput, 300);
|
|
54028
54302
|
const [typeFilters, setTypeFilters] = (0, react$1.useState)(() => [...initialTypeFilters]);
|
|
@@ -54071,6 +54345,7 @@ function GenericModeList(props) {
|
|
|
54071
54345
|
getFilterType
|
|
54072
54346
|
]);
|
|
54073
54347
|
const totalItems = filtered.length;
|
|
54348
|
+
const pageSize = pageSizeSelector ? effectivePageSize(chosenPageSize, totalItems) : fixedPageSize;
|
|
54074
54349
|
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
54075
54350
|
const safePage = Math.min(page, totalPages);
|
|
54076
54351
|
const startIdx = (safePage - 1) * pageSize;
|
|
@@ -54154,7 +54429,23 @@ function GenericModeList(props) {
|
|
|
54154
54429
|
}),
|
|
54155
54430
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
54156
54431
|
className: "shrink-0",
|
|
54157
|
-
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, {
|
|
54158
54449
|
currentPage: safePage,
|
|
54159
54450
|
totalItems,
|
|
54160
54451
|
pageSize,
|
|
@@ -54283,6 +54574,24 @@ var DeviceItemRowSchema = zod.z.object({
|
|
|
54283
54574
|
});
|
|
54284
54575
|
var SupportedKindsSchema = zod.z.array(zod.z.string());
|
|
54285
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
|
+
};
|
|
54286
54595
|
/**
|
|
54287
54596
|
* The fleet-list poll. Deliberately the same 30 s as the window
|
|
54288
54597
|
* `applyFleetQueryDefaults` registers for `deviceManager.listAll` (D274) —
|
|
@@ -54367,6 +54676,35 @@ function SetupSection({ setup }) {
|
|
|
54367
54676
|
})]
|
|
54368
54677
|
});
|
|
54369
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
|
+
}
|
|
54370
54708
|
/**
|
|
54371
54709
|
* Per-row Expose/Exposed toggle. Reflects whether the row's device is exposed
|
|
54372
54710
|
* to THIS exporter and flips it through the SAME runner the bulk buttons use —
|
|
@@ -54445,7 +54783,7 @@ function BulkSummary({ outcome, onDismiss }) {
|
|
|
54445
54783
|
* Generic device-export panel. Addon-agnostic — only the `device-export`
|
|
54446
54784
|
* cap drives it.
|
|
54447
54785
|
*/
|
|
54448
|
-
function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
54786
|
+
function DeviceExportPanel({ addonId, onOpenDevice, showSetup = true }) {
|
|
54449
54787
|
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
54450
54788
|
const statusQuery = useDeviceExportGetStatus({
|
|
54451
54789
|
nodeId: "hub",
|
|
@@ -54471,10 +54809,7 @@ function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
|
54471
54809
|
}, [queryClient]);
|
|
54472
54810
|
const exposeMutation = useDeviceExportExposeDevice({ onSuccess: invalidate });
|
|
54473
54811
|
const unexposeMutation = useDeviceExportUnexposeDevice({ onSuccess: invalidate });
|
|
54474
|
-
const status = (0, react$1.useMemo)(() =>
|
|
54475
|
-
const parsed = _camstack_types.DeviceExportStatusSchema.safeParse(statusQuery.data);
|
|
54476
|
-
return parsed.success ? parsed.data : null;
|
|
54477
|
-
}, [statusQuery.data]);
|
|
54812
|
+
const status = (0, react$1.useMemo)(() => parseStatus(statusQuery.data), [statusQuery.data]);
|
|
54478
54813
|
const exposed = (0, react$1.useMemo)(() => {
|
|
54479
54814
|
const parsed = ExposedDeviceArraySchema.safeParse(exposedQuery.data);
|
|
54480
54815
|
return parsed.success ? parsed.data : [];
|
|
@@ -54697,11 +55032,11 @@ function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
|
54697
55032
|
]
|
|
54698
55033
|
}), loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin text-foreground-subtle" })]
|
|
54699
55034
|
}),
|
|
54700
|
-
status?.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
55035
|
+
showSetup && status?.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
54701
55036
|
className: "px-2 sm:px-4 py-3 border-b border-border",
|
|
54702
55037
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBox, { message: status.error })
|
|
54703
55038
|
}),
|
|
54704
|
-
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 }),
|
|
54705
55040
|
outcome !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BulkSummary, {
|
|
54706
55041
|
outcome,
|
|
54707
55042
|
onDismiss: dismissOutcome
|
|
@@ -54721,6 +55056,7 @@ function DeviceExportPanel({ addonId, onOpenDevice }) {
|
|
|
54721
55056
|
columns,
|
|
54722
55057
|
onRowClick: onOpenDevice ? onRowClick : void 0,
|
|
54723
55058
|
toolbar: selectionToolbar,
|
|
55059
|
+
pageSizeSelector: DEVICE_EXPORT_PAGE_SIZE,
|
|
54724
55060
|
searchPlaceholder: "Search by name or stableId",
|
|
54725
55061
|
emptyLabel: "No device matches this search."
|
|
54726
55062
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, {
|
|
@@ -54746,145 +55082,6 @@ function DeviceGrid({ children, minCardWidth = 220, gap = 3, className }) {
|
|
|
54746
55082
|
});
|
|
54747
55083
|
}
|
|
54748
55084
|
//#endregion
|
|
54749
|
-
//#region src/composites/icon-picker.tsx
|
|
54750
|
-
/**
|
|
54751
|
-
* icon-picker — the ONE control for choosing an icon, wherever admin-ui asks.
|
|
54752
|
-
*
|
|
54753
|
-
* There were two: a device one over `DISPLAY_ICON_REGISTRY` and a room one
|
|
54754
|
-
* over `LOCATION_ICON_IDS`, identical apart from the vocabulary they walked.
|
|
54755
|
-
* That was tolerable while the device set was 56 glyphs in a flat grid. It is
|
|
54756
|
-
* not at 157: a picker that only lets the operator HUNT is a picker they stop
|
|
54757
|
-
* using, and the two copies were already drifting — only one of them had an
|
|
54758
|
-
* i18n'd label.
|
|
54759
|
-
*
|
|
54760
|
-
* So the vocabulary, the grouping and the search all come from
|
|
54761
|
-
* `@camstack/types`' `display-icon-vocabulary`, which is the same module the
|
|
54762
|
-
* viewer's sheet searches. What is left here is the web half: a popover, a
|
|
54763
|
-
* grid, and a text field.
|
|
54764
|
-
*
|
|
54765
|
-
* ## What it does NOT own
|
|
54766
|
-
*
|
|
54767
|
-
* - **The glyphs.** `resolveGlyph` is a prop, because this package's table is
|
|
54768
|
-
* `lucide-react` and the viewer's is `lucide-react-native`. A key this build
|
|
54769
|
-
* cannot draw is SKIPPED rather than rendered as a hole — an empty tile
|
|
54770
|
-
* reads as a rendering bug, not as a missing choice.
|
|
54771
|
-
* - **The words.** Every string is a prop. This package has no i18n (one file
|
|
54772
|
-
* in it imports react-i18next, and that is the exception), and a control
|
|
54773
|
-
* that reached for a translation would force it on every consumer.
|
|
54774
|
-
* - **The write.** `onPick` is called and that is all; whether it is a form
|
|
54775
|
-
* value or an immediate mutation is the caller's business, as it already was
|
|
54776
|
-
* in both pickers this replaces.
|
|
54777
|
-
*
|
|
54778
|
-
* ## The clear tile is never filtered away
|
|
54779
|
-
*
|
|
54780
|
-
* The "inherit" / "no icon" choice sits above the sections and ignores the
|
|
54781
|
-
* search. A query that hid it would strand the operator on a glyph they picked
|
|
54782
|
-
* by accident with no way back to the default — the one action a picker must
|
|
54783
|
-
* always offer.
|
|
54784
|
-
*/
|
|
54785
|
-
function IconPicker({ value, onPick, resolveGlyph, fallbackGlyph, labels, only, extraWords, clearGlyph, labelFor, disabled = false }) {
|
|
54786
|
-
const [open, setOpen] = (0, react$1.useState)(false);
|
|
54787
|
-
const [query, setQuery] = (0, react$1.useState)("");
|
|
54788
|
-
const allowed = (0, react$1.useMemo)(() => only === void 0 ? null : new Set(only), [only]);
|
|
54789
|
-
const sections = (0, react$1.useMemo)(() => {
|
|
54790
|
-
const hits = (0, _camstack_types.searchDisplayIcons)(query, extraWords);
|
|
54791
|
-
const byGroup = /* @__PURE__ */ new Map();
|
|
54792
|
-
for (const hit of hits) {
|
|
54793
|
-
const { key, group } = hit.entry;
|
|
54794
|
-
if (allowed !== null && !allowed.has(key)) continue;
|
|
54795
|
-
if (resolveGlyph(key) === void 0) continue;
|
|
54796
|
-
const bucket = byGroup.get(group);
|
|
54797
|
-
if (bucket === void 0) byGroup.set(group, [key]);
|
|
54798
|
-
else bucket.push(key);
|
|
54799
|
-
}
|
|
54800
|
-
return _camstack_types.DISPLAY_ICON_GROUPS.flatMap((group) => {
|
|
54801
|
-
const keys = byGroup.get(group);
|
|
54802
|
-
return keys === void 0 || keys.length === 0 ? [] : [{
|
|
54803
|
-
group,
|
|
54804
|
-
keys
|
|
54805
|
-
}];
|
|
54806
|
-
});
|
|
54807
|
-
}, [
|
|
54808
|
-
query,
|
|
54809
|
-
extraWords,
|
|
54810
|
-
allowed,
|
|
54811
|
-
resolveGlyph
|
|
54812
|
-
]);
|
|
54813
|
-
const Current = (value === null ? void 0 : resolveGlyph(value)) ?? fallbackGlyph;
|
|
54814
|
-
const choose = async (next) => {
|
|
54815
|
-
setOpen(false);
|
|
54816
|
-
setQuery("");
|
|
54817
|
-
await onPick(next);
|
|
54818
|
-
};
|
|
54819
|
-
const Clear = clearGlyph ?? fallbackGlyph;
|
|
54820
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
54821
|
-
className: "relative flex shrink-0 items-center gap-2",
|
|
54822
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
54823
|
-
type: "button",
|
|
54824
|
-
disabled,
|
|
54825
|
-
onClick: () => setOpen((o) => !o),
|
|
54826
|
-
"aria-expanded": open,
|
|
54827
|
-
"aria-label": labels.trigger,
|
|
54828
|
-
title: labels.trigger,
|
|
54829
|
-
className: "rounded border border-border p-1 text-foreground-muted hover:bg-surface-hover disabled:opacity-50",
|
|
54830
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Current, { className: "h-4 w-4" })
|
|
54831
|
-
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
54832
|
-
type: "button",
|
|
54833
|
-
"aria-label": labels.close,
|
|
54834
|
-
onClick: () => setOpen(false),
|
|
54835
|
-
className: "fixed inset-0 z-10 cursor-default"
|
|
54836
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
54837
|
-
role: "group",
|
|
54838
|
-
"aria-label": labels.panel,
|
|
54839
|
-
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",
|
|
54840
|
-
children: [
|
|
54841
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
54842
|
-
type: "search",
|
|
54843
|
-
value: query,
|
|
54844
|
-
autoFocus: true,
|
|
54845
|
-
onChange: (e) => setQuery(e.target.value),
|
|
54846
|
-
placeholder: labels.searchPlaceholder,
|
|
54847
|
-
"aria-label": labels.searchPlaceholder,
|
|
54848
|
-
className: "mb-2 w-full rounded border border-border bg-surface-raised px-2 py-1 text-xs text-foreground placeholder:text-foreground-subtle"
|
|
54849
|
-
}),
|
|
54850
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
54851
|
-
type: "button",
|
|
54852
|
-
onClick: () => void choose(null),
|
|
54853
|
-
"aria-pressed": value === null,
|
|
54854
|
-
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",
|
|
54855
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Clear, { className: "h-3.5 w-3.5" }), labels.clear]
|
|
54856
|
-
}),
|
|
54857
|
-
sections.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
54858
|
-
className: "px-1.5 py-2 text-[11px] text-foreground-subtle",
|
|
54859
|
-
children: labels.noMatches
|
|
54860
|
-
}) : sections.map(({ group, keys }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
54861
|
-
className: "mb-2 last:mb-0",
|
|
54862
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
54863
|
-
className: "px-1.5 pb-1 text-[10px] uppercase tracking-wide text-foreground-subtle",
|
|
54864
|
-
children: labels.groups[group]
|
|
54865
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
54866
|
-
className: "grid grid-cols-7 gap-1",
|
|
54867
|
-
children: keys.map((key) => {
|
|
54868
|
-
const Glyph = resolveGlyph(key);
|
|
54869
|
-
if (Glyph === void 0) return null;
|
|
54870
|
-
const selected = value === key;
|
|
54871
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
54872
|
-
type: "button",
|
|
54873
|
-
onClick: () => void choose(key),
|
|
54874
|
-
"aria-pressed": selected,
|
|
54875
|
-
"aria-label": labelFor?.(key) ?? key,
|
|
54876
|
-
title: labelFor?.(key) ?? key,
|
|
54877
|
-
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",
|
|
54878
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Glyph, { className: "h-4 w-4" })
|
|
54879
|
-
}, key);
|
|
54880
|
-
})
|
|
54881
|
-
})]
|
|
54882
|
-
}, group))
|
|
54883
|
-
]
|
|
54884
|
-
})] })]
|
|
54885
|
-
});
|
|
54886
|
-
}
|
|
54887
|
-
//#endregion
|
|
54888
55085
|
//#region src/composites/device-selector-picker.tsx
|
|
54889
55086
|
/**
|
|
54890
55087
|
* <DeviceSelectorPicker> — the operator-facing editor for a v3
|
|
@@ -61085,6 +61282,7 @@ exports.CoverPanel = CoverPanel;
|
|
|
61085
61282
|
exports.CustomFieldRenderersProvider = CustomFieldRenderersProvider;
|
|
61086
61283
|
exports.DEFAULT_COLOR = DEFAULT_COLOR;
|
|
61087
61284
|
exports.DEVICE_COLUMNS = DEVICE_COLUMNS;
|
|
61285
|
+
exports.DEVICE_EXPORT_PAGE_SIZE_KEY = DEVICE_EXPORT_PAGE_SIZE_KEY;
|
|
61088
61286
|
exports.DEVICE_LIST_PAGE_SIZE_KEY = DEVICE_LIST_PAGE_SIZE_KEY;
|
|
61089
61287
|
exports.DEVICE_LIST_PAGE_SIZE_OPTIONS = DEVICE_LIST_PAGE_SIZE_OPTIONS;
|
|
61090
61288
|
exports.DEVICE_PICKER_GROUP_STORAGE_KEY = DEVICE_PICKER_GROUP_STORAGE_KEY;
|
|
@@ -61103,6 +61301,7 @@ exports.DeviceBatchToolbar = DeviceBatchToolbar;
|
|
|
61103
61301
|
exports.DeviceCard = DeviceCard;
|
|
61104
61302
|
exports.DeviceContextProvider = DeviceContextProvider;
|
|
61105
61303
|
exports.DeviceExportPanel = DeviceExportPanel;
|
|
61304
|
+
exports.DeviceExportSetup = DeviceExportSetup;
|
|
61106
61305
|
exports.DeviceFilterBar = DeviceFilterBar;
|
|
61107
61306
|
exports.DeviceGrid = DeviceGrid;
|
|
61108
61307
|
exports.DeviceItem = DeviceItem;
|
|
@@ -61216,6 +61415,7 @@ exports.NotificationTargetsField = NotificationTargetsField;
|
|
|
61216
61415
|
exports.OPTION_SELECT_SEARCH_MIN_OPTIONS = OPTION_SELECT_SEARCH_MIN_OPTIONS;
|
|
61217
61416
|
exports.OfflineBadge = OfflineBadge;
|
|
61218
61417
|
exports.OptionSelect = OptionSelect;
|
|
61418
|
+
exports.PAGE_SIZE_ALL = PAGE_SIZE_ALL;
|
|
61219
61419
|
exports.PHASE_CONFIG = PHASE_CONFIG;
|
|
61220
61420
|
exports.PICKER_CHIP_LIMIT = PICKER_CHIP_LIMIT;
|
|
61221
61421
|
exports.PICKER_DEFAULT_GROUP_BY = PICKER_DEFAULT_GROUP_BY;
|
|
@@ -61230,6 +61430,7 @@ exports.PICKER_WINDOW = PICKER_WINDOW;
|
|
|
61230
61430
|
exports.PRIORITY = PRIORITY;
|
|
61231
61431
|
exports.PTZOverlay = PTZOverlay;
|
|
61232
61432
|
exports.PageHeader = PageHeader;
|
|
61433
|
+
exports.PageSizeSelect = PageSizeSelect;
|
|
61233
61434
|
exports.PhaseIcon = PhaseIcon;
|
|
61234
61435
|
exports.PipelineBuilder = PipelineBuilder;
|
|
61235
61436
|
exports.PipelineRuntimeSelector = PipelineRuntimeSelector;
|
|
@@ -61402,6 +61603,7 @@ exports.deviceTypeMetaOf = deviceTypeMetaOf;
|
|
|
61402
61603
|
exports.devicesToOptions = devicesToOptions;
|
|
61403
61604
|
exports.dockBox = dockBox;
|
|
61404
61605
|
exports.draftFromQuery = draftFromQuery;
|
|
61606
|
+
exports.effectivePageSize = effectivePageSize;
|
|
61405
61607
|
exports.emptyDevicesWidens = emptyDevicesWidens;
|
|
61406
61608
|
exports.emptySessionRun = emptySessionRun;
|
|
61407
61609
|
exports.ensureMfHostInit = ensureMfHostInit;
|
|
@@ -61464,6 +61666,7 @@ exports.optionSelectSearchText = optionSearchText;
|
|
|
61464
61666
|
exports.orphanDeviceLabel = orphanDeviceLabel;
|
|
61465
61667
|
exports.overrideEntityIdFromLink = overrideEntityIdFromLink;
|
|
61466
61668
|
exports.pageRows = pageRows;
|
|
61669
|
+
exports.pageSizeLabel = pageSizeLabel;
|
|
61467
61670
|
exports.parentDetailOf = parentDetailOf;
|
|
61468
61671
|
exports.parseIceCandidate = parseIceCandidate;
|
|
61469
61672
|
exports.parsePickerGroupBy = parsePickerGroupBy;
|
|
@@ -61564,6 +61767,7 @@ exports.useAddonsIsWorkspaceAvailable = useAddonsIsWorkspaceAvailable;
|
|
|
61564
61767
|
exports.useAddonsList = useAddonsList;
|
|
61565
61768
|
exports.useAddonsListCapabilityProviders = useAddonsListCapabilityProviders;
|
|
61566
61769
|
exports.useAddonsListFrameworkPackages = useAddonsListFrameworkPackages;
|
|
61770
|
+
exports.useAddonsListInstallations = useAddonsListInstallations;
|
|
61567
61771
|
exports.useAddonsListJobs = useAddonsListJobs;
|
|
61568
61772
|
exports.useAddonsListPackages = useAddonsListPackages;
|
|
61569
61773
|
exports.useAddonsListUpdates = useAddonsListUpdates;
|
|
@@ -62173,6 +62377,7 @@ exports.useOsdManagerSetSlotBinding = useOsdManagerSetSlotBinding;
|
|
|
62173
62377
|
exports.useOsdManagerUpsertTemplate = useOsdManagerUpsertTemplate;
|
|
62174
62378
|
exports.useOsdSetOverlay = useOsdSetOverlay;
|
|
62175
62379
|
exports.usePTZ = usePTZ;
|
|
62380
|
+
exports.usePersistedPageSize = usePersistedPageSize;
|
|
62176
62381
|
exports.usePetFeederCallPet = usePetFeederCallPet;
|
|
62177
62382
|
exports.usePetFeederCancelFeed = usePetFeederCancelFeed;
|
|
62178
62383
|
exports.usePetFeederFeed = usePetFeederFeed;
|
|
@@ -62250,12 +62455,14 @@ exports.usePipelineAnalyticsResumeForStorageMigration = usePipelineAnalyticsResu
|
|
|
62250
62455
|
exports.usePipelineAnalyticsSaveRetrainAnnotations = usePipelineAnalyticsSaveRetrainAnnotations;
|
|
62251
62456
|
exports.usePipelineAnalyticsSearchObjectEvents = usePipelineAnalyticsSearchObjectEvents;
|
|
62252
62457
|
exports.usePipelineAnalyticsSelectRetrainFrames = usePipelineAnalyticsSelectRetrainFrames;
|
|
62458
|
+
exports.usePipelineAnalyticsSetRetrainFrameComplete = usePipelineAnalyticsSetRetrainFrameComplete;
|
|
62253
62459
|
exports.usePipelineAnalyticsSetTrackFlags = usePipelineAnalyticsSetTrackFlags;
|
|
62254
62460
|
exports.usePipelineAnalyticsSetTrackPurity = usePipelineAnalyticsSetTrackPurity;
|
|
62255
62461
|
exports.usePipelineAnalyticsSetTrackRelation = usePipelineAnalyticsSetTrackRelation;
|
|
62256
62462
|
exports.usePipelineAnalyticsStartStorageMigrationMove = usePipelineAnalyticsStartStorageMigrationMove;
|
|
62257
62463
|
exports.usePipelineAnalyticsWipeAllAnalytics = usePipelineAnalyticsWipeAllAnalytics;
|
|
62258
62464
|
exports.usePipelineAnalyticsWipeObjectEmbeddings = usePipelineAnalyticsWipeObjectEmbeddings;
|
|
62465
|
+
exports.usePipelineAnalyticsWriteRetrainArchive = usePipelineAnalyticsWriteRetrainArchive;
|
|
62259
62466
|
exports.usePipelineExecutorCacheFrameInPool = usePipelineExecutorCacheFrameInPool;
|
|
62260
62467
|
exports.usePipelineExecutorClearDeviceOverrides = usePipelineExecutorClearDeviceOverrides;
|
|
62261
62468
|
exports.usePipelineExecutorClearModelBoundDeviceOverrides = usePipelineExecutorClearModelBoundDeviceOverrides;
|
|
@@ -62637,8 +62844,11 @@ exports.useUserManagementCreateScopedToken = useUserManagementCreateScopedToken;
|
|
|
62637
62844
|
exports.useUserManagementCreateUser = useUserManagementCreateUser;
|
|
62638
62845
|
exports.useUserManagementDeleteUser = useUserManagementDeleteUser;
|
|
62639
62846
|
exports.useUserManagementDisableTotp = useUserManagementDisableTotp;
|
|
62847
|
+
exports.useUserManagementFindUserByExternalIdentity = useUserManagementFindUserByExternalIdentity;
|
|
62640
62848
|
exports.useUserManagementGetTotpStatus = useUserManagementGetTotpStatus;
|
|
62849
|
+
exports.useUserManagementLinkExternalIdentity = useUserManagementLinkExternalIdentity;
|
|
62641
62850
|
exports.useUserManagementListApiKeys = useUserManagementListApiKeys;
|
|
62851
|
+
exports.useUserManagementListExternalIdentities = useUserManagementListExternalIdentities;
|
|
62642
62852
|
exports.useUserManagementListOauthSessions = useUserManagementListOauthSessions;
|
|
62643
62853
|
exports.useUserManagementListScopedTokens = useUserManagementListScopedTokens;
|
|
62644
62854
|
exports.useUserManagementListUsers = useUserManagementListUsers;
|
|
@@ -62652,6 +62862,7 @@ exports.useUserManagementRevokeOauthSession = useUserManagementRevokeOauthSessio
|
|
|
62652
62862
|
exports.useUserManagementRevokeScopedToken = useUserManagementRevokeScopedToken;
|
|
62653
62863
|
exports.useUserManagementSetUserScopes = useUserManagementSetUserScopes;
|
|
62654
62864
|
exports.useUserManagementSetupTotp = useUserManagementSetupTotp;
|
|
62865
|
+
exports.useUserManagementUnlinkExternalIdentity = useUserManagementUnlinkExternalIdentity;
|
|
62655
62866
|
exports.useUserManagementUpdateUser = useUserManagementUpdateUser;
|
|
62656
62867
|
exports.useUserManagementValidateApiKey = useUserManagementValidateApiKey;
|
|
62657
62868
|
exports.useUserManagementValidateCredentials = useUserManagementValidateCredentials;
|