@camstack/addon-admin-ui 1.2.89 → 1.2.94
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/assets/AddLocationWizard-Sek5QLaR.js +1 -0
- package/dist/assets/{AddonCollectionPage-Czx0Rf1Y.js → AddonCollectionPage-BlBmDAbs.js} +1 -1
- package/dist/assets/{Addons-X9onTcjm.js → Addons-gvoz8a4O.js} +1 -1
- package/dist/assets/{AdminTabs-BFe9RXxD.js → AdminTabs-DsvLDV_X.js} +1 -1
- package/dist/assets/{AiProfiles-DS7dcd3T.js → AiProfiles-DjVGSKHV.js} +1 -1
- package/dist/assets/{BrokerForm-RC8ZQms1.js → BrokerForm-Dvm37TsV.js} +1 -1
- package/dist/assets/{Build-DYatQ35G.js → Build-Cev8UG20.js} +1 -1
- package/dist/assets/{Capabilities-CdAjZZ5u.js → Capabilities-C0NzxpFZ.js} +1 -1
- package/dist/assets/{CapabilityBadges-mGyqruK0.js → CapabilityBadges-DptkwryH.js} +1 -1
- package/dist/assets/{Cluster-CIp91ynz.js → Cluster-CVoXEcJX.js} +1 -1
- package/dist/assets/Data-BtEtI0hl.js +1 -0
- package/dist/assets/{DetectionIntelligence-D80ddmLz.js → DetectionIntelligence-D0V6XC3g.js} +1 -1
- package/dist/assets/{DeviceAggregateSection-CmXH0Z_0.js → DeviceAggregateSection-pJF0I0ji.js} +1 -1
- package/dist/assets/DeviceDetail-6uL50jAw.js +2 -0
- package/dist/assets/{Devices-C8E4qBqs.js → Devices-D9UrHlBx.js} +1 -1
- package/dist/assets/{EmbedPlayerPage-nLTLNYPt.js → EmbedPlayerPage-3gvOP1Lo.js} +1 -1
- package/dist/assets/Events-BpFlDRCZ.js +1 -0
- package/dist/assets/{FormBuilder-CgXBJs1A.js → FormBuilder-n-gtxKKP.js} +1 -1
- package/dist/assets/Identity-BGrqpL6R.js +1 -0
- package/dist/assets/{IntegrationDetail-CRrZPmmb.js → IntegrationDetail-B5fX1Rfh.js} +1 -1
- package/dist/assets/{Integrations-CXvB3xLb.js → Integrations-BmR6rCw3.js} +1 -1
- package/dist/assets/{Integrations-CnscVQeA.js → Integrations-CvLcUMC1.js} +1 -1
- package/dist/assets/{Logs-Ptalp9Ap.js → Logs-CvvIJmdu.js} +1 -1
- package/dist/assets/{MotionZonesSettings-GG2onGsd.js → MotionZonesSettings-D730Ohsw.js} +1 -1
- package/dist/assets/{MyAccess-C9X6mSCC.js → MyAccess-S-zPnlmV.js} +1 -1
- package/dist/assets/Network-CuyR4l8n.js +1 -0
- package/dist/assets/{NodeAddonsSettingsPanel-BYXH3-BP.js → NodeAddonsSettingsPanel-DpR1uZ4x.js} +1 -1
- package/dist/assets/{NodeInferenceDevices-CJBU3t4h.js → NodeInferenceDevices-DKuIaw4S.js} +1 -1
- package/dist/assets/Notifications-DgJJH18r.js +1 -0
- package/dist/assets/Pipeline-twyzj8t1.js +1 -0
- package/dist/assets/{Plates-DzZx4BPp.js → Plates-CKPPLty5.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-DlD5nHl0.js → PrivacyMaskSettings-CwVFFv-s.js} +1 -1
- package/dist/assets/{ProviderIcon-DaauzRy3.js → ProviderIcon-BcDfIAjC.js} +1 -1
- package/dist/assets/Recordings-Dqxb3yWj.js +1 -0
- package/dist/assets/{ScanNetworkModal-DwKJwpIs.js → ScanNetworkModal-CZotzs7Y.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-H2Z_9riR.js → SceneMonitorEditor-BPWDxHyV.js} +1 -1
- package/dist/assets/{Scenes-DiJCcvjG.js → Scenes-CfrZoXbO.js} +1 -1
- package/dist/assets/{Settings-Clokst-N.js → Settings-Desvli4Y.js} +1 -1
- package/dist/assets/{Showroom-1ViARhyC.js → Showroom-wuDLoVIa.js} +1 -1
- package/dist/assets/{Terminal-mLwOsOgP.js → Terminal-BlZ5ho6K.js} +3 -3
- package/dist/assets/_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-5HHutopH.js +1 -0
- package/dist/assets/{bell-ring-BPrVhIE4.js → bell-ring-CEwCH3Tn.js} +1 -1
- package/dist/assets/{boxes-89UouT8T.js → boxes-BZXILdSW.js} +1 -1
- package/dist/assets/{build-cluster-graph-Cbb1I-jq.js → build-cluster-graph-DNS5rxFE.js} +1 -1
- package/dist/assets/circle-check-big-CsY6BeBv.js +1 -0
- package/dist/assets/{circle-x-Bsgek5uU.js → circle-x-Bew5Q_nP.js} +1 -1
- package/dist/assets/clock-CFKZCC35.js +1 -0
- package/dist/assets/{copy-BtDJ2xWI.js → copy-cKuRyng6.js} +1 -1
- package/dist/assets/{debounced-invalidate-CfMppTLk.js → debounced-invalidate-Y0Fq7XP6.js} +1 -1
- package/dist/assets/dist-CSVCtpQj.js +349 -0
- package/dist/assets/dist-Y-7sn4sd.js +1 -0
- package/dist/assets/{download-DrTCm0Zn.js → download-CeWNRvq3.js} +1 -1
- package/dist/assets/{face-bbox-bnTYLJ2C.js → face-bbox-BHUQurhO.js} +1 -1
- package/dist/assets/{format-size-CO9d3C3-.js → format-size-DIxKXxtj.js} +1 -1
- package/dist/assets/hostInit-gY59vcky.js +1 -0
- package/dist/assets/{index-D7fwM52p.js → index-Lc0dE1cs.js} +3 -3
- package/dist/assets/{key-round-PssF2mH1.js → key-round-CaC1XjAw.js} +1 -1
- package/dist/assets/{mf-entry-bootstrap-0-12df8905.js → mf-entry-bootstrap-0-a4457b48.js} +2 -2
- package/dist/assets/{pencil-DDE9Ut_f.js → pencil-rkgakXwV.js} +1 -1
- package/dist/assets/play-BirAgXbB.js +1 -0
- package/dist/assets/{player-overlays-DsK1iDkv.js → player-overlays-CNH4a5GP.js} +1 -1
- package/dist/assets/plus-1BHo3JQ0.js +1 -0
- package/dist/assets/power-DvLECIA6.js +1 -0
- package/dist/assets/{radio-Cgg_wmnh.js → radio-BSZTDMVf.js} +1 -1
- package/dist/assets/{refresh-cw-B06QF6BP.js → refresh-cw-DjuW2TND.js} +1 -1
- package/dist/assets/remoteEntry-CtxyXHbj.js +1 -0
- package/dist/assets/rotate-ccw-FPxxEiag.js +1 -0
- package/dist/assets/rotate-cw-CT3CqdoN.js +1 -0
- package/dist/assets/search-C0G57bg-.js +1 -0
- package/dist/assets/{send-CCB7-Bua.js → send-CDzERjMI.js} +1 -1
- package/dist/assets/{server-qRR4BT4Q.js → server-Coea8IU2.js} +1 -1
- package/dist/assets/{shield-Dhep2Fkd.js → shield-BgTzTj9u.js} +1 -1
- package/dist/assets/square-9yGHC4jm.js +1 -0
- package/dist/assets/{square-check-big-CKJTPtsS.js → square-check-big-CVD39Ip_.js} +1 -1
- package/dist/assets/src-BeMyEWoU.js +67 -0
- package/dist/assets/src-OKGaFXeI.js +349 -0
- package/dist/assets/{star-Cfry0hZj.js → star-CT2UVvEV.js} +1 -1
- package/dist/assets/{undo-2-CP7k5Csp.js → undo-2-CjSDypn2.js} +1 -1
- package/dist/assets/{upload-DKCLx4MR.js → upload-pn_jgYxZ.js} +1 -1
- package/dist/assets/{use-scenes-feed-Cf4dSlYi.js → use-scenes-feed-VBEy5qvK.js} +1 -1
- package/dist/assets/useEventInvalidation-BaJsurQc.js +1 -0
- package/dist/assets/{video-LCt0QHTC.js → video-DT6QFuTd.js} +1 -1
- package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-D-HrWJSs.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-Dy_l5X-d.js} +2 -2
- package/dist/assets/{wifi-BHTVIRt4.js → wifi-BXfUpS7s.js} +1 -1
- package/dist/assets/{zap-BXQ1pVxK.js → zap-BRY3F81c.js} +1 -1
- package/dist/index.html +5 -5
- package/dist/server/addon.js +136 -18
- package/package.json +1 -1
- package/dist/assets/AddLocationWizard-CYxP8ICv.js +0 -1
- package/dist/assets/Data-CmrUXYoi.js +0 -1
- package/dist/assets/DeviceDetail-CY4j2jrm.js +0 -2
- package/dist/assets/Events-vfLnBqsv.js +0 -1
- package/dist/assets/Identity-C-6ig3ru.js +0 -1
- package/dist/assets/Network-DdfJzcEJ.js +0 -1
- package/dist/assets/Notifications-DVfJp0YC.js +0 -1
- package/dist/assets/Pipeline-YNTCsnOx.js +0 -1
- package/dist/assets/Recordings-i9RDqe2o.js +0 -1
- package/dist/assets/_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-BTd_JgZ5.js +0 -1
- package/dist/assets/circle-check-big-D9ynSOrO.js +0 -1
- package/dist/assets/clock-BvQlDL5a.js +0 -1
- package/dist/assets/dist-BJIJtrLw.js +0 -1
- package/dist/assets/dist-BVCWYzWk.js +0 -349
- package/dist/assets/hard-drive-D6wUZdNf.js +0 -1
- package/dist/assets/hostInit-ZAX9mo8c.js +0 -1
- package/dist/assets/play-VJTjxs_g.js +0 -1
- package/dist/assets/plus-CKJhtG9S.js +0 -1
- package/dist/assets/power-DIX0P9O_.js +0 -1
- package/dist/assets/remoteEntry-GRBshePF.js +0 -1
- package/dist/assets/rotate-ccw-CHuGPAms.js +0 -1
- package/dist/assets/rotate-cw-B7IVurj2.js +0 -1
- package/dist/assets/search-B9qXKjRG.js +0 -1
- package/dist/assets/square-CfRn6ZFd.js +0 -1
- package/dist/assets/src-DY4vbC0g.js +0 -349
- package/dist/assets/src-DnZ6ZcH0.js +0 -67
- package/dist/assets/useEventInvalidation-CINdEbPJ.js +0 -1
package/dist/server/addon.js
CHANGED
|
@@ -8014,6 +8014,15 @@ var LabelDefinitionSchema = object({
|
|
|
8014
8014
|
description: string().optional(),
|
|
8015
8015
|
icon: string().optional()
|
|
8016
8016
|
});
|
|
8017
|
+
var ClassMapDefinitionSchema = object({
|
|
8018
|
+
mapping: record(string(), _enum([
|
|
8019
|
+
"person",
|
|
8020
|
+
"vehicle",
|
|
8021
|
+
"animal",
|
|
8022
|
+
"package"
|
|
8023
|
+
])),
|
|
8024
|
+
preserveOriginal: boolean()
|
|
8025
|
+
});
|
|
8017
8026
|
var MODEL_FORMATS = [
|
|
8018
8027
|
"onnx",
|
|
8019
8028
|
"coreml",
|
|
@@ -8192,7 +8201,13 @@ var ModelCatalogEntrySchema = object({
|
|
|
8192
8201
|
* `id` stays the source of truth for resolution/download/persistence; grouping
|
|
8193
8202
|
* is a presentation overlay resolved back to an `id`.
|
|
8194
8203
|
*/
|
|
8195
|
-
group: ModelVariantGroupSchema.optional()
|
|
8204
|
+
group: ModelVariantGroupSchema.optional(),
|
|
8205
|
+
/**
|
|
8206
|
+
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
8207
|
+
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
8208
|
+
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
8209
|
+
*/
|
|
8210
|
+
classMap: ClassMapDefinitionSchema.optional()
|
|
8196
8211
|
});
|
|
8197
8212
|
var ConvertTargetSchema = discriminatedUnion("format", [object({
|
|
8198
8213
|
format: literal("openvino"),
|
|
@@ -8221,7 +8236,8 @@ var ModelConvertMetadataSchema = object({
|
|
|
8221
8236
|
"ocr",
|
|
8222
8237
|
"segmentation"
|
|
8223
8238
|
]),
|
|
8224
|
-
faceAlignment: boolean().optional()
|
|
8239
|
+
faceAlignment: boolean().optional(),
|
|
8240
|
+
classMap: ClassMapDefinitionSchema.optional()
|
|
8225
8241
|
});
|
|
8226
8242
|
var ConvertResultSchema = object({
|
|
8227
8243
|
entry: ModelCatalogEntrySchema,
|
|
@@ -14360,12 +14376,15 @@ var NcOccupancyConditionSchema = object({
|
|
|
14360
14376
|
* there is no second switch that can disagree with the first and every rule
|
|
14361
14377
|
* authored before the decision migrates for free (`audioModeOf`):
|
|
14362
14378
|
*
|
|
14363
|
-
* - **LABEL mode — `labels` present.** The rule fires
|
|
14364
|
-
*
|
|
14365
|
-
* `hitPercent` and `samplingSeconds` are ignored
|
|
14366
|
-
*
|
|
14367
|
-
*
|
|
14368
|
-
*
|
|
14379
|
+
* - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
|
|
14380
|
+
* labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
|
|
14381
|
+
* `hitPercent` and `samplingSeconds` are still ignored — a percentage of
|
|
14382
|
+
* frames is the wrong question for a classifier that labels 1–3 frames
|
|
14383
|
+
* per episode. The count window is the brake that drops a single-frame
|
|
14384
|
+
* false positive; the rule's own `throttle` cooldown is the other. The
|
|
14385
|
+
* per-label confidence floor is the analyzer's (`classificationMinScore`,
|
|
14386
|
+
* per device) — a label only reaches this condition if the classifier was
|
|
14387
|
+
* already confident enough. `confirmHits: 1` restores first-frame fire.
|
|
14369
14388
|
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
14370
14389
|
* the condition: at least `hitPercent`% of the samples over
|
|
14371
14390
|
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
@@ -14392,14 +14411,22 @@ var NcOccupancyConditionSchema = object({
|
|
|
14392
14411
|
* an operator who typed `dog` mean the same thing.
|
|
14393
14412
|
*/
|
|
14394
14413
|
var NcAudioConditionSchema = object({
|
|
14395
|
-
/** LABEL MODE: audio macro labels. Present ⇒
|
|
14414
|
+
/** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
|
|
14396
14415
|
labels: array(string().min(1)).min(1).optional(),
|
|
14397
14416
|
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
14398
14417
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
14399
14418
|
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
14400
14419
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
14401
14420
|
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
14402
|
-
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
14421
|
+
samplingSeconds: number().int().min(1).max(300).default(10),
|
|
14422
|
+
/**
|
|
14423
|
+
* LABEL MODE: how many labelled frames must land inside
|
|
14424
|
+
* {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
|
|
14425
|
+
* Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
|
|
14426
|
+
*/
|
|
14427
|
+
confirmHits: number().int().min(1).max(20).optional(),
|
|
14428
|
+
/** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
|
|
14429
|
+
confirmWindowSec: number().int().min(1).max(60).optional()
|
|
14403
14430
|
});
|
|
14404
14431
|
/**
|
|
14405
14432
|
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
@@ -16848,7 +16875,9 @@ var TrackCascadeCountsSchema = object({
|
|
|
16848
16875
|
/** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
|
|
16849
16876
|
plates: number().int(),
|
|
16850
16877
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
16851
|
-
embeddings: number().int()
|
|
16878
|
+
embeddings: number().int(),
|
|
16879
|
+
/** Group membership + group rows removed with their last member (best-effort). */
|
|
16880
|
+
groups: number().int()
|
|
16852
16881
|
});
|
|
16853
16882
|
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
16854
16883
|
var DiskReconcileCountsSchema = object({
|
|
@@ -17212,6 +17241,33 @@ var NativeCropRefSchema = object({
|
|
|
17212
17241
|
h: number()
|
|
17213
17242
|
})
|
|
17214
17243
|
});
|
|
17244
|
+
object({
|
|
17245
|
+
crop: object({
|
|
17246
|
+
left: number(),
|
|
17247
|
+
top: number(),
|
|
17248
|
+
width: number().positive(),
|
|
17249
|
+
height: number().positive()
|
|
17250
|
+
}).optional(),
|
|
17251
|
+
content: object({
|
|
17252
|
+
width: number().int().positive(),
|
|
17253
|
+
height: number().int().positive()
|
|
17254
|
+
}),
|
|
17255
|
+
fit: _enum(["stretch", "contain"]),
|
|
17256
|
+
format: _enum([
|
|
17257
|
+
"rgb",
|
|
17258
|
+
"gray",
|
|
17259
|
+
"jpeg"
|
|
17260
|
+
])
|
|
17261
|
+
});
|
|
17262
|
+
var FrameRefSchema = object({
|
|
17263
|
+
registryId: string().min(1),
|
|
17264
|
+
id: string().min(1),
|
|
17265
|
+
width: number().int().positive(),
|
|
17266
|
+
height: number().int().positive(),
|
|
17267
|
+
format: _enum(["rgb", "gray"]),
|
|
17268
|
+
timestamp: number(),
|
|
17269
|
+
capturedAt: number().optional()
|
|
17270
|
+
});
|
|
17215
17271
|
var ModelFormatSchema$1 = _enum([
|
|
17216
17272
|
"onnx",
|
|
17217
17273
|
"coreml",
|
|
@@ -17456,6 +17512,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
17456
17512
|
steps: array(PipelineStepInputSchema).min(1),
|
|
17457
17513
|
frame: FrameInputSchema.optional(),
|
|
17458
17514
|
/**
|
|
17515
|
+
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
17516
|
+
* in the same execution-group process; split/cross-node callers use
|
|
17517
|
+
* `frame`/`image` inline compatibility instead.
|
|
17518
|
+
*/
|
|
17519
|
+
frameRef: FrameRefSchema.optional(),
|
|
17520
|
+
/**
|
|
17459
17521
|
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
17460
17522
|
* the decoded pixels live in. One more member of the one-of
|
|
17461
17523
|
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
@@ -17711,7 +17773,10 @@ var NativeCropResultSchema = object({
|
|
|
17711
17773
|
* Which source served this crop, so a quality-sensitive consumer (the native
|
|
17712
17774
|
* `keyFrame`) can reject a degraded fallback:
|
|
17713
17775
|
* - `native` — cut from the decode worker's retained NATIVE surface (the
|
|
17714
|
-
* quality path).
|
|
17776
|
+
* quality path). A subject-tile serve is also native-resolution and stays
|
|
17777
|
+
* `native` here: the public enum cannot name `tile` without a breaking cap
|
|
17778
|
+
* change. Runner telemetry distinguishes lease vs tile via `source` on the
|
|
17779
|
+
* internal crop result (`nativeHits` vs `tileHits`).
|
|
17715
17780
|
* - `ram-fullframe` — the native surface MISSED but the request was full-frame,
|
|
17716
17781
|
* so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
|
|
17717
17782
|
* the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
|
|
@@ -18202,12 +18267,41 @@ var RunnerLocalLoadSchema = object({
|
|
|
18202
18267
|
* legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
|
|
18203
18268
|
* working unchanged when they switch to reading from the runner cap.
|
|
18204
18269
|
*/
|
|
18270
|
+
var FrameLazyCountersSchema = object({
|
|
18271
|
+
framesDecoded: number(),
|
|
18272
|
+
framesAdmitted: number(),
|
|
18273
|
+
framesDroppedPixelFree: number(),
|
|
18274
|
+
viewsMaterialized: number(),
|
|
18275
|
+
viewsSkipped: number(),
|
|
18276
|
+
workerToRunnerBytes: number(),
|
|
18277
|
+
runnerToPoolRawBytes: number(),
|
|
18278
|
+
runnerToPoolJpegBytes: number(),
|
|
18279
|
+
onDemandFullFrameRequests: number(),
|
|
18280
|
+
onDemandCropRequests: number(),
|
|
18281
|
+
nativeHits: number(),
|
|
18282
|
+
nativeMisses: number(),
|
|
18283
|
+
tileHits: number(),
|
|
18284
|
+
tileMisses: number(),
|
|
18285
|
+
fallbackHits: number(),
|
|
18286
|
+
fallbackMisses: number(),
|
|
18287
|
+
retainedWritesAvoided: number(),
|
|
18288
|
+
residentRefs: number(),
|
|
18289
|
+
residentBytes: number(),
|
|
18290
|
+
releases: number(),
|
|
18291
|
+
evictions: number(),
|
|
18292
|
+
staleMisses: number()
|
|
18293
|
+
});
|
|
18294
|
+
var FrameLazyMetricsSchema = object({
|
|
18295
|
+
node: FrameLazyCountersSchema,
|
|
18296
|
+
cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
|
|
18297
|
+
});
|
|
18205
18298
|
var RunnerLocalMetricsSchema = object({
|
|
18206
18299
|
nodeId: string(),
|
|
18207
18300
|
activeCameras: number(),
|
|
18208
18301
|
throttledCameras: number(),
|
|
18209
18302
|
avgInferenceTimeMs: number(),
|
|
18210
|
-
queueDepth: number()
|
|
18303
|
+
queueDepth: number(),
|
|
18304
|
+
frameLazy: FrameLazyMetricsSchema.optional()
|
|
18211
18305
|
});
|
|
18212
18306
|
method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
|
|
18213
18307
|
handle: FrameHandleSchema,
|
|
@@ -22576,6 +22670,17 @@ var NotificationEndpointSchema = object({
|
|
|
22576
22670
|
/** What the ranking currently resolves to (null when nothing is reachable). */
|
|
22577
22671
|
resolved: string().nullable()
|
|
22578
22672
|
});
|
|
22673
|
+
/**
|
|
22674
|
+
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
22675
|
+
* AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
|
|
22676
|
+
* currently expands to, so the UI can show the effective set either way.
|
|
22677
|
+
*/
|
|
22678
|
+
var ViewerEndpointsSchema = object({
|
|
22679
|
+
/** The operator's explicit race set, or empty for AUTO. */
|
|
22680
|
+
baseUrls: array(string()).readonly(),
|
|
22681
|
+
/** What the ranking currently resolves to (may be empty if nothing is up). */
|
|
22682
|
+
resolved: array(string()).readonly()
|
|
22683
|
+
});
|
|
22579
22684
|
var AllowedAddressesSchema = object({
|
|
22580
22685
|
/**
|
|
22581
22686
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -22607,17 +22712,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
22607
22712
|
*/
|
|
22608
22713
|
port: number().int().min(1).max(65535).optional(),
|
|
22609
22714
|
/** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
|
|
22610
|
-
* candidate. Default `
|
|
22715
|
+
* candidate. Default `false` — loopback is not a client route. */
|
|
22611
22716
|
includeLoopback: boolean().optional(),
|
|
22612
|
-
/** Skip IPv6 entries.
|
|
22613
|
-
*
|
|
22717
|
+
/** Skip IPv6 entries. Default `false` — the palette includes stable
|
|
22718
|
+
* LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
|
|
22719
|
+
* hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
|
|
22614
22720
|
ipv4Only: boolean().optional(),
|
|
22615
22721
|
/** Scheme to emit for LAN/loopback URLs. Default `'http'`.
|
|
22616
22722
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
22617
22723
|
* to avoid mixed-content blocks in the browser. The public
|
|
22618
22724
|
* tunnel always emits `https://` regardless. */
|
|
22619
22725
|
scheme: _enum(["http", "https"]).optional()
|
|
22620
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
22726
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
22621
22727
|
kind: "mutation",
|
|
22622
22728
|
auth: "admin"
|
|
22623
22729
|
}), method(object({
|
|
@@ -28429,6 +28535,12 @@ Object.freeze({
|
|
|
28429
28535
|
addonId: null,
|
|
28430
28536
|
access: "view"
|
|
28431
28537
|
},
|
|
28538
|
+
"localNetwork.getViewerEndpoints": {
|
|
28539
|
+
capName: "local-network",
|
|
28540
|
+
capScope: "system",
|
|
28541
|
+
addonId: null,
|
|
28542
|
+
access: "view"
|
|
28543
|
+
},
|
|
28432
28544
|
"localNetwork.list": {
|
|
28433
28545
|
capName: "local-network",
|
|
28434
28546
|
capScope: "system",
|
|
@@ -28465,6 +28577,12 @@ Object.freeze({
|
|
|
28465
28577
|
addonId: null,
|
|
28466
28578
|
access: "create"
|
|
28467
28579
|
},
|
|
28580
|
+
"localNetwork.setViewerEndpoints": {
|
|
28581
|
+
capName: "local-network",
|
|
28582
|
+
capScope: "system",
|
|
28583
|
+
addonId: null,
|
|
28584
|
+
access: "create"
|
|
28585
|
+
},
|
|
28468
28586
|
"localNetwork.uploadCertificate": {
|
|
28469
28587
|
capName: "local-network",
|
|
28470
28588
|
capScope: "system",
|
|
@@ -34041,7 +34159,7 @@ var AdminUIAddon = class extends BaseAddon {
|
|
|
34041
34159
|
capability: adminUiCapability,
|
|
34042
34160
|
provider: {
|
|
34043
34161
|
getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
|
|
34044
|
-
getVersion: async () => ({ version: "1.2.
|
|
34162
|
+
getVersion: async () => ({ version: "1.2.94" })
|
|
34045
34163
|
}
|
|
34046
34164
|
}];
|
|
34047
34165
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as e,Q as t,S as n,W as r,a as i,o as a,q as o,x as s,z as c}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DhP-Lgiq.js";import{Z as l}from"./player-overlays-DsK1iDkv.js";import{Go as u,Xo as d,g as f}from"./src-DnZ6ZcH0.js";import{t as p}from"./FormBuilder-CgXBJs1A.js";import{t as m}from"./pencil-DDE9Ut_f.js";import{t as h}from"./plus-CKJhtG9S.js";import{t as g}from"./power-DIX0P9O_.js";import{t as _}from"./star-Cfry0hZj.js";import{C as v,I as y,i as b,s as x}from"./index-D7fwM52p.js";t();function S(e){return e.enabled!==!1}function C(e){return e.isDefault}function w(e,t){let n={id:e.id,type:e.type,displayName:t.displayName??e.displayName,providerId:e.providerId,config:e.config,isDefault:t.isDefault??e.isDefault,isSystem:e.isSystem},r=e.nodeId===void 0?n:{...n,nodeId:e.nodeId},i=t.enabled??e.enabled;return i===void 0?r:{...r,enabled:i}}function T(e){return`${(e/1024**3).toFixed(e>=100*1024**3?0:1)} GB`}function E({location:e}){let t=e.capacity;return t==null?null:n(`span`,{className:`text-[10px] text-foreground-subtle tabular-nums`,children:[T(t.availableBytes),` free of `,T(t.totalBytes)]})}function D(e){let t=e.basePath;if(typeof t==`string`&&t.length>0)return t;let n=Object.keys(e);return n.length===0?``:n.join(`, `)}function O({location:e,cardinality:t,onEdit:r,onDelete:i,onSetDefault:a,onToggleEnabled:o}){let c=D(e.config),l=S(e),u=C(e);return n(`div`,{className:`flex flex-wrap items-center gap-x-3 gap-y-2 px-3 py-2 border-t border-border first:border-t-0 hover:bg-primary/5`,children:[n(`div`,{className:`flex flex-wrap items-center gap-2 min-w-0 flex-1 basis-64`,children:[s(`div`,{className:`w-[88px] shrink-0`,children:e.isDefault?n(`span`,{className:`inline-flex items-center gap-0.5 rounded bg-primary/10 border border-primary/20 px-1.5 py-0.5 text-[10px] font-semibold text-primary uppercase tracking-wide`,title:`Default location for this type`,children:[s(_,{className:`h-2.5 w-2.5 fill-primary`}),`Default`]}):n(`button`,{onClick:()=>a(e),className:`inline-flex items-center gap-0.5 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-foreground-subtle hover:text-foreground hover:bg-primary/10 hover:border-primary/30 uppercase tracking-wide`,title:`Promote to default for this type`,children:[s(_,{className:`h-2.5 w-2.5`}),`Set default`]})}),s(`span`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5 font-mono`,children:e.providerId}),!l&&s(`span`,{className:`text-[10px] uppercase tracking-wide text-warning bg-warning/10 border border-warning/30 rounded px-1.5 py-0.5`,title:`Disabled — nothing new is written here. Existing data stays readable and is still pruned by age.`,children:`disabled`}),e.isSystem&&s(`span`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5`,title:`System-managed location — cannot be deleted; edit config to relocate`,children:`system`}),e.config.readOnly===!0&&s(`span`,{className:`text-[10px] uppercase tracking-wide text-warning bg-warning/10 border border-warning/30 rounded px-1.5 py-0.5`,title:`Drain mode — reads and age retention continue; nothing new is written here and disk-pressure eviction skips it`,children:`read-only`}),n(`div`,{className:`min-w-0`,children:[s(`div`,{className:`text-xs font-medium text-foreground truncate`,children:e.displayName}),n(`div`,{className:`flex flex-wrap items-center gap-x-2`,children:[c&&s(`span`,{className:`text-[10px] text-foreground-subtle truncate font-mono`,children:c}),s(E,{location:e})]})]})]}),n(`div`,{className:`flex flex-wrap items-center gap-1 shrink-0`,children:[n(`button`,{type:`button`,role:`switch`,"aria-label":`Writes enabled`,"aria-checked":l,disabled:u,onClick:()=>o(e,!l),title:u?`The default location of a type is always enabled — it is the fallback every balancing consumer falls back to. Promote another location to default first.`:l?`Enabled — balancing consumers may write new data here. Click to stop new writes.`:`Disabled — no new data is written here. Existing data stays readable. Click to enable.`,className:`inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium border disabled:cursor-not-allowed ${l?`border-success/30 text-success hover:bg-success/10`:`border-warning/40 text-warning hover:bg-warning/10`}`,children:[s(g,{className:`h-3 w-3`}),l?`Enabled`:`Disabled`]}),!e.isDefault&&n(`button`,{onClick:()=>a(e),className:`inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle border border-border hover:text-foreground hover:bg-primary/10`,title:`Set as default for this type`,children:[s(_,{className:`h-3 w-3`}),`Set default`]}),n(`button`,{onClick:()=>r(e),className:`inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle border border-border hover:text-foreground hover:bg-primary/10`,children:[s(m,{className:`h-3 w-3`}),`Edit`]}),!e.isSystem&&t!==`single`&&s(`button`,{onClick:()=>i(e),className:`inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-danger hover:bg-danger/10`,title:`Delete location`,children:s(x,{className:`h-3 w-3`})})]})]})}function k({type:e,displayName:t,description:i,cardinality:a,locations:o,onAdd:c,onEdit:l,onDelete:u,onSetDefault:d,onToggleEnabled:f}){let p=r(()=>{let e=[...o];return e.sort((e,t)=>e.isDefault===t.isDefault?e.displayName.localeCompare(t.displayName):e.isDefault?-1:1),e},[o]);return n(`div`,{className:`rounded-lg border border-border bg-surface`,children:[n(`div`,{className:`flex items-start justify-between border-b border-border px-3 py-2`,children:[n(`div`,{className:`space-y-0.5`,children:[n(`div`,{className:`flex items-center gap-2`,children:[s(`span`,{className:`text-sm font-semibold text-foreground capitalize`,children:t}),s(`span`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5 font-mono`,children:e})]}),i&&s(`p`,{className:`text-[11px] text-foreground-subtle`,children:i}),a===`single`&&s(`p`,{className:`text-[10px] text-foreground-subtle italic`,children:`Single — one location per type. Edit the existing entry; it can't be split.`})]}),a===`multi`&&n(`button`,{onClick:()=>c(e),className:`inline-flex items-center gap-1 rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90`,children:[s(h,{className:`h-3 w-3`}),`Add`]})]}),p.length===0?s(`div`,{className:`px-3 py-4 text-center text-[11px] text-foreground-subtle italic`,children:a===`multi`?`No location registered. Click "Add" to register one.`:`No location registered yet — should be auto-seeded at next boot.`}):s(`div`,{children:p.map(e=>s(O,{location:e,cardinality:a,onEdit:l,onDelete:u,onSetDefault:d,onToggleEnabled:f},e.id))})]})}var A=new Set([`proc`,`sys`,`dev`,`run`,`boot`,`lost+found`,`snap`,`bin`,`sbin`,`lib`,`lib32`,`lib64`,`libx32`,`usr`,`etc`,`var`,`opt`,`tmp`,`srv`,`root`,`System`,`Library`,`Applications`,`cores`,`private`]),j=[`recordings`,`data`,`mnt`,`media`,`Volumes`];function M(e){let t=j.findIndex(t=>t===`recordings`?e.startsWith(t):e===t);return t===-1?j.length:t}function N(e){return e.filter(e=>!e.name.startsWith(`.`)&&!A.has(e.name)).toSorted((e,t)=>{let n=M(e.name)-M(t.name);return n===0?e.name.localeCompare(t.name):n}).map(e=>e.path)}t();function P({nodeId:t,value:r,onChange:i}){let a=l().trpcClient,[u,d]=o([]),[f,p]=o(r),[m,h]=o(null),[g,_]=o(null),[v,y]=o(``),b=e(async(e,n)=>{_(null);try{let r=await a.filesystemBrowse.browse.query({nodeId:t,path:e});h(r),p(r.path),n&&i(r.path)}catch(e){_(e instanceof Error?e.message:`browse failed`)}},[a,t,i]);c(()=>{p(r),(async()=>{let e=await a.filesystemBrowse.browse.query({nodeId:t,path:`/`}).then(e=>e).catch(()=>null);if(e){d(N(e.entries)),await b(r.startsWith(`/`)?r:`/`,!1);return}try{let e=await a.filesystemBrowse.listAllowedRoots.query({nodeId:t});d(e),await b(r&&e.some(e=>r.startsWith(e))?r:e[0]??``,!1)}catch(e){d([]),h(null),_(e instanceof Error&&/not available on node/i.test(e.message)?`This node can't be browsed remotely. Enter the path manually.`:e instanceof Error?e.message:`browse unavailable`)}})()},[t]);let x=async()=>{if(!(!v.trim()||!m)){_(null);try{let e=`${m.path.replace(/\/+$/,``)}/${v.trim()}`;await a.filesystemBrowse.createDir.mutate({nodeId:t,path:e}),y(``),await b(m.path,!0)}catch(e){_(e instanceof Error?e.message:`create failed`)}}},S=e=>`${(e/1e9).toFixed(1)} GB`;return n(`div`,{className:`space-y-2 rounded border border-border p-2`,children:[s(`div`,{className:`flex flex-wrap gap-1`,children:u.map(e=>s(`button`,{onClick:()=>void b(e,!0),className:`rounded border border-border px-2 py-0.5 text-[10px] font-mono hover:border-primary/40`,children:e},e))}),s(`input`,{value:f,onChange:e=>{p(e.target.value),i(e.target.value)},placeholder:`/absolute/path`,className:`w-full rounded border border-border bg-background px-2 py-1 text-[11px] font-mono`}),m&&n(`div`,{className:`text-[10px] text-foreground-subtle`,children:[S(m.freeBytes),` free / `,S(m.totalBytes)]}),s(`div`,{className:`max-h-40 space-y-0.5 overflow-y-auto`,children:m?.entries.map(e=>n(`button`,{onClick:()=>void b(e.path,!0),className:`block w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-primary/5`,children:[`📁 `,e.name]},e.path))}),n(`div`,{className:`flex gap-1`,children:[s(`input`,{value:v,onChange:e=>y(e.target.value),placeholder:`new folder`,className:`flex-1 rounded border border-border bg-background px-2 py-1 text-xs`}),s(`button`,{onClick:()=>void x(),className:`rounded border border-border px-2 py-1 text-xs hover:border-primary/40`,children:`Create`})]}),g&&s(`div`,{className:`text-[10px] text-red-400`,children:g})]})}t();function F({location:e,onClose:t,onSaved:c}){let m=a(),h=l().trpcClient,[g,_]=o({...e.config}),[y,x]=o(e.displayName),[S,C]=o(null),[w,T]=o(!1),E=u(),D=r(()=>{let t=E.data;return Array.isArray(t)?t.find(t=>t.providerId===e.providerId)??null:null},[E.data,e.providerId]),O=d({onSuccess:()=>{m.invalidateQueries({queryKey:[[`storage`,`listLocations`]]}),c()}}),k=D?.shouldSaveDiskSpace===!0,A=D?.nodeLocal===!0,[j,M]=o(typeof e.nodeId==`string`?e.nodeId:`hub`),N=typeof g.basePath==`string`?g.basePath:``,F=e=>_(t=>({...t,basePath:e})),I=g.readOnly===!0,L=i({queryKey:[`storage`,`listLocations`,`ro-guard`],queryFn:()=>h.storage.listLocations.query({})}),R=(L.data??[]).filter(t=>t.type===e.type&&t.id!==e.id&&t.config.readOnly!==!0).length,z=!I&&L.data!==void 0&&R===0,B=e=>_(t=>{let n={...t};return delete n.readOnly,e?{...n,readOnly:!0}:n}),V=typeof g.maxUsedGb==`number`?g.maxUsedGb:``,H=e=>{let t=e.trim(),n=t===``?void 0:Number(t);_(e=>{let t={...e};return n===void 0||!Number.isFinite(n)||n<=0?delete t.maxUsedGb:t.maxUsedGb=n,t})},U=typeof g.minFreePercent==`number`?g.minFreePercent:``,W=e=>{let t=e.trim(),n=t===``?void 0:Number(t);_(e=>{let t={...e};return n===void 0||!Number.isFinite(n)?delete t.minFreePercent:t.minFreePercent=Math.min(100,Math.max(0,n)),t})},G=async()=>{T(!0),C(null);try{C(await(e=>h.storage.testConfig.query(e))({providerId:e.providerId,config:g}))}catch(e){C({ok:!1,error:e instanceof Error?e.message:String(e)})}finally{T(!1)}};return s(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm`,onClick:t,children:n(`div`,{className:`w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl`,onClick:e=>e.stopPropagation(),children:[n(`div`,{className:`flex items-start justify-between border-b border-border px-4 py-3`,children:[n(`div`,{className:`space-y-0.5`,children:[n(`h2`,{className:`text-sm font-semibold text-foreground`,children:[`Edit `,e.displayName]}),n(`p`,{className:`text-xs text-foreground-subtle`,children:[s(`span`,{className:`font-mono`,children:e.id}),` ·`,` `,D?.displayName??e.providerId]})]}),s(`button`,{onClick:t,className:`text-foreground-subtle hover:text-foreground`,children:s(b,{className:`h-4 w-4`})})]}),n(`div`,{className:`p-4 space-y-3 max-h-[60vh] overflow-y-auto`,children:[n(`div`,{className:`space-y-1`,children:[s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Display name`}),s(`input`,{type:`text`,value:y,onChange:e=>x(e.target.value),className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary`})]}),D&&s(p,{schema:D.configSchema,values:g,onChange:_}),n(`div`,{className:`space-y-1`,children:[n(`label`,{className:`flex items-center gap-2 text-xs ${z?`text-foreground-subtle cursor-not-allowed`:`text-foreground cursor-pointer`}`,children:[s(`input`,{type:`checkbox`,checked:I,disabled:z,onChange:e=>B(e.target.checked),className:`accent-primary`}),`Read-only (drain mode)`]}),s(`p`,{className:`text-[10px] text-foreground-subtle`,children:z?`Blocked: this is the last writable location of its type — new footage would have nowhere to go.`:`Reads and age-based retention continue; nothing new is written here and disk-pressure eviction skips it. Use it to slowly decommission a disk.`})]}),A&&n(`div`,{className:`space-y-2`,children:[s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Node`}),s(f,{selectedNodeId:j,onSelect:M,alwaysShow:!0}),s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Path`}),s(P,{nodeId:j,value:N,onChange:F})]}),k&&n(`div`,{className:`space-y-1`,children:[s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Min free disk %`}),s(`input`,{type:`number`,min:0,max:100,value:U,placeholder:D?.minFreePercent==null?``:String(D.minFreePercent),onChange:e=>W(e.target.value),className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary`}),n(`p`,{className:`text-[10px] text-foreground-subtle`,children:[`When free space on this volume drops below this %, the oldest data stored here is evicted to reclaim space.`,D?.minFreePercent==null?` Empty = use the default.`:` Empty = use the default (${D.minFreePercent}%).`]}),s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Max used (GB)`}),s(`input`,{type:`number`,min:1,value:V,placeholder:`unlimited`,onChange:e=>H(e.target.value),className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary`}),s(`p`,{className:`text-[10px] text-foreground-subtle`,children:`Hard cap on the TOTAL bytes evictable data (recordings) may occupy on this location, independent of disk free space — oldest footage is evicted past it. Empty = unlimited.`})]}),!D&&!E.isLoading&&n(`div`,{className:`rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-700 dark:text-amber-300`,children:[`Provider `,s(`code`,{className:`font-mono`,children:e.providerId}),` is no longer registered. Field schema unavailable; raw config is preserved on save.`]}),S&&s(`div`,{className:`rounded border px-3 py-2 text-[11px] ${S.ok?`border-success/30 bg-success/5 text-success`:`border-danger/30 bg-danger/5 text-danger`}`,children:S.ok?`Connection OK.`:`Test failed: ${S.error??`unknown error`}`}),O.isError&&s(`div`,{className:`rounded border border-danger/30 bg-danger/5 text-danger px-3 py-2 text-[11px]`,children:O.error instanceof Error?O.error.message:String(O.error)})]}),n(`div`,{className:`flex items-center justify-between gap-2 border-t border-border px-4 py-3`,children:[s(`button`,{onClick:t,className:`rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground`,children:`Cancel`}),n(`div`,{className:`flex items-center gap-2`,children:[s(`button`,{onClick:()=>{G()},disabled:w||!D,className:`rounded border border-border px-3 py-1.5 text-xs text-foreground hover:bg-primary/10 disabled:opacity-50`,children:w?`Testing…`:`Test connection`}),n(`button`,{onClick:()=>{O.mutate({id:e.id,type:e.type,providerId:e.providerId,isDefault:e.isDefault,displayName:y.trim(),config:g,nodeId:A?j:void 0})},disabled:O.isPending||y.trim().length===0,className:`inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50`,children:[O.isPending?s(v,{className:`h-3.5 w-3.5 animate-spin`}):null,O.isPending?`Saving…`:`Save`]})]})]})]})})}function I(e){let t=e.trim().toLowerCase();return t.length===0?``:t.replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}function L(e,t){let n=I(t);return`${e}:${n.length>0?n:`default`}`}t();function R({initialType:e,onClose:t,onCreated:i}){let c=a(),m=l().trpcClient,[h,g]=o(`picker`),[_,x]=o(e),[S,C]=o(null),[w,T]=o({}),[E,D]=o(``),[O,k]=o(null),[A,j]=o(!1),[M,N]=o(!1),[F,I]=o(`hub`),[R,z]=o(null),[B,V]=o(!1),H=e=>T(t=>({...t,basePath:e})),U=typeof w.basePath==`string`?w.basePath:``,W=u(),G=r(()=>{let e=W.data;return Array.isArray(e)?e:[]},[W.data]),K=W.isLoading,q=d({onSuccess:()=>{c.invalidateQueries({queryKey:[[`storage`,`listLocations`]]}),i()}}),J=r(()=>O!==null&&O.length>0?O:L(_,E),[_,E,O]),Y=async()=>{if(S){V(!0),z(null);try{z(await(e=>m.storage.testConfig.query(e))({providerId:S.providerId,config:w}))}catch(e){z({ok:!1,error:e instanceof Error?e.message:String(e)})}finally{V(!1)}}};return s(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm`,onClick:t,children:n(`div`,{className:`w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl`,onClick:e=>e.stopPropagation(),children:[n(`div`,{className:`flex items-start justify-between border-b border-border px-4 py-3`,children:[n(`div`,{className:`space-y-0.5`,children:[s(`h2`,{className:`text-sm font-semibold text-foreground`,children:{picker:`Add Location — Pick provider`,config:`Add Location — ${S?.displayName??``}`,naming:`Add Location — Name & defaults`}[h]}),n(`p`,{className:`text-xs text-foreground-subtle`,children:[`Type: `,s(`span`,{className:`font-mono`,children:_})]})]}),s(`button`,{onClick:t,className:`text-foreground-subtle hover:text-foreground`,children:s(b,{className:`h-4 w-4`})})]}),h===`picker`&&n(`div`,{className:`p-4 space-y-2`,children:[K&&s(`div`,{className:`text-xs text-foreground-subtle animate-pulse`,children:`Loading providers…`}),!K&&G.length===0&&n(`div`,{className:`rounded border border-border bg-background px-3 py-4 text-center text-xs text-foreground-subtle`,children:[`No storage-provider supports type "`,_,`". Install a compatible addon (e.g.`,` `,s(`code`,{className:`font-mono`,children:`remote-storage`}),`) to enable it.`]}),G.map(e=>n(`button`,{onClick:()=>{C(e),g(`config`)},className:`flex w-full items-center gap-3 rounded-lg border border-border bg-background p-3 text-left hover:border-primary/40 hover:bg-primary/5 transition-colors`,children:[n(`div`,{className:`flex-1 min-w-0`,children:[s(`p`,{className:`text-xs font-semibold text-foreground`,children:e.displayName}),s(`p`,{className:`text-[10px] text-foreground-subtle font-mono mt-0.5 truncate`,children:e.providerId})]}),s(y,{className:`h-4 w-4 text-foreground-subtle flex-shrink-0`})]},e.providerId))]}),h===`config`&&S&&n(`div`,{className:`p-4 space-y-3 max-h-[60vh] overflow-y-auto`,children:[s(p,{schema:S.configSchema,values:w,onChange:T}),S.nodeLocal&&n(`div`,{className:`space-y-2`,children:[s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Node`}),s(f,{selectedNodeId:F,onSelect:I,alwaysShow:!0}),s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Path`}),s(P,{nodeId:F,value:U,onChange:H})]}),R&&s(`div`,{className:`rounded border px-3 py-2 text-[11px] ${R.ok?`border-success/30 bg-success/5 text-success`:`border-danger/30 bg-danger/5 text-danger`}`,children:R.ok?`Connection OK.`:`Test failed: ${R.error??`unknown error`}`}),n(`div`,{className:`flex items-center justify-between pt-1`,children:[s(`button`,{onClick:()=>g(`picker`),className:`rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground`,children:`Back`}),n(`div`,{className:`flex items-center gap-2`,children:[s(`button`,{onClick:()=>{Y()},disabled:B,className:`rounded border border-border px-3 py-1.5 text-xs text-foreground hover:bg-primary/10 disabled:opacity-50`,children:B?`Testing…`:`Test connection`}),s(`button`,{onClick:()=>g(`naming`),className:`rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90`,children:`Next`})]})]})]}),h===`naming`&&S&&n(`div`,{className:`p-4 space-y-3`,children:[n(`div`,{className:`space-y-1`,children:[s(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Display name`}),s(`input`,{type:`text`,value:E,onChange:e=>D(e.target.value),placeholder:`${_} on ${S.displayName}`,className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary`})]}),n(`div`,{className:`space-y-1`,children:[n(`label`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:[`Id`,` `,s(`span`,{className:`lowercase tracking-normal text-foreground-subtle`,children:`— auto-derived; override if needed`})]}),s(`input`,{type:`text`,value:J,onChange:e=>k(e.target.value),placeholder:L(_,E),className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground font-mono focus:outline-none focus:ring-1 focus:ring-primary`}),n(`p`,{className:`text-[10px] text-foreground-subtle`,children:[`Format: `,s(`code`,{className:`font-mono`,children:`<type>:<slug>`}),`. Lowercase letters, digits, and hyphens only.`]})]}),n(`label`,{className:`flex items-start gap-2 rounded border border-border bg-background px-3 py-2 cursor-pointer hover:bg-primary/5`,children:[s(`input`,{type:`checkbox`,checked:A,onChange:e=>j(e.target.checked),className:`accent-primary mt-0.5`}),n(`div`,{className:`space-y-0.5`,children:[n(`div`,{className:`text-xs font-medium text-foreground`,children:[`Mark as default for type "`,_,`"`]}),n(`div`,{className:`text-[10px] text-foreground-subtle`,children:[`Setting this as default will demote the current default for this type. References like `,n(`code`,{className:`font-mono`,children:[`"`,_,`"`]}),` resolve to whichever location is the default.`]})]})]}),n(`label`,{className:`flex items-start gap-2 rounded border border-border bg-background px-3 py-2 cursor-pointer hover:bg-primary/5`,children:[s(`input`,{type:`checkbox`,checked:M,onChange:e=>N(e.target.checked),className:`accent-primary mt-0.5`}),n(`div`,{className:`space-y-0.5`,children:[s(`div`,{className:`text-xs font-medium text-foreground`,children:`Enable immediately`}),s(`div`,{className:`text-[10px] text-foreground-subtle`,children:`A disabled location receives no writes until enabled — reads and age-based retention still work, nothing new lands here. Leave this off to register the disk now and start using it later.`})]})]}),q.isError&&s(`div`,{className:`rounded border border-danger/30 bg-danger/5 text-danger px-3 py-2 text-[11px]`,children:q.error instanceof Error?q.error.message:String(q.error)}),n(`div`,{className:`flex items-center justify-between pt-1`,children:[s(`button`,{onClick:()=>g(`config`),className:`rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground`,children:`Back`}),n(`div`,{className:`flex items-center gap-2`,children:[s(`button`,{onClick:()=>{x(e),C(null),T({}),D(``),k(null),j(!1),N(!1),z(null),g(`picker`)},className:`rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground`,children:`Reset`}),n(`button`,{onClick:()=>{S&&q.mutate({id:J,type:_,displayName:E.trim(),providerId:S.providerId,config:w,isDefault:A,enabled:M,nodeId:S.nodeLocal?F:void 0})},disabled:q.isPending||E.trim().length===0,className:`inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50`,children:[q.isPending?s(v,{className:`h-3.5 w-3.5 animate-spin`}):null,q.isPending?`Saving…`:`Save`]})]})]})]})]})})}export{w as i,F as n,k as r,R as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as e,Q as t,S as n,W as r,b as i,o as a,q as o,x as s,z as c}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DhP-Lgiq.js";import{$n as l,Dn as u,En as d,Ho as f,Jn as p,Mn as m,Qn as h,Uo as g,Wo as _,Xn as v,Xo as y,Yn as b,Zn as x,er as S,ln as C,nr as w,rr as T,tr as E}from"./src-DnZ6ZcH0.js";import{t as D}from"./download-DrTCm0Zn.js";import{t as O}from"./hard-drive-D6wUZdNf.js";import{t as k}from"./pencil-DDE9Ut_f.js";import{t as A}from"./play-VJTjxs_g.js";import{t as j}from"./plus-CKJhtG9S.js";import{t as M}from"./rotate-cw-B7IVurj2.js";import{C as N,I as P,K as F,R as I,W as ee,i as L,m as R,s as z}from"./index-D7fwM52p.js";import{t as B}from"./AdminPage-CCD07UMs.js";import{r as te}from"./authed-media-BPd_L9jr.js";import{t as ne}from"./AdminTabs-BFe9RXxD.js";import{t as V}from"./format-size-CO9d3C3-.js";import{i as H,n as re,r as ie,t as ae}from"./AddLocationWizard-CYxP8ICv.js";import{t as U}from"./AddonCollectionPage-Czx0Rf1Y.js";import{t as W}from"./addon-display-names-DvSEQty-.js";var G=F(`archive`,[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8`,key:`1s80jp`}],[`path`,{d:`M10 12h4`,key:`a56b0p`}]]),K=F(`arrow-right`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]),q=F(`calendar-clock`,[[`path`,{d:`M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5`,key:`1osxxc`}],[`path`,{d:`M16 2v4`,key:`4m81vk`}],[`path`,{d:`M8 2v4`,key:`1cmpym`}],[`path`,{d:`M3 10h5`,key:`r794hk`}],[`path`,{d:`M17.5 17.5 16 16.3V14`,key:`akvzfd`}],[`circle`,{cx:`16`,cy:`16`,r:`6`,key:`qoo3c4`}]]),J=F(`file-text`,[[`path`,{d:`M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z`,key:`1rqfz7`}],[`path`,{d:`M14 2v4a2 2 0 0 0 2 2h4`,key:`tnqrlb`}],[`path`,{d:`M10 9H8`,key:`b1mrlr`}],[`path`,{d:`M16 13H8`,key:`t4e002`}],[`path`,{d:`M16 17H8`,key:`z1uh3a`}]]);t();function oe(){let e=a(),t=C(),{data:i,isLoading:c,isError:l}=_({}),u=g(),d=r(()=>u.data??[],[u.data]),[p,m]=o(null),[h,v]=o(null),b=f({onSuccess:()=>{e.invalidateQueries({queryKey:[[`storage`,`listLocations`]]})}}),x=y({onSuccess:()=>{e.invalidateQueries({queryKey:[[`storage`,`listLocations`]]})}}),S=e=>{e.isDefault||x.mutate(H(e,{isDefault:!0}))},w=(e,t)=>{x.mutate(H(e,{enabled:t}))},T=async e=>{if(e.isDefault){await t({title:`Cannot delete default location`,message:`"${e.displayName}" is the default for type "${e.type}". Mark another location as default first, then delete this one.`,confirmLabel:`OK`,variant:`warning`});return}await t({title:`Delete location "${e.displayName}"?`,message:`This removes the location record. Files on disk are not deleted; the underlying directory or remote path stays untouched.`,confirmLabel:`Delete`,variant:`danger`})&&b.mutate({id:e.id})},E=r(()=>{let e=new Map;for(let t of i??[]){let n=e.get(t.type);n?n.push(t):e.set(t.type,[t])}return e},[i]),D=c||u.isLoading,O=l||u.isError;return n(B,{children:[D&&s(`div`,{className:`text-xs text-foreground-subtle animate-pulse`,children:`Loading locations…`}),O&&s(`div`,{className:`text-xs text-danger`,children:`Failed to load storage locations.`}),!D&&!O&&n(`div`,{className:`space-y-3`,children:[d.length===0&&s(`div`,{className:`rounded-lg border border-border bg-surface px-3 py-4 text-center text-[11px] text-foreground-subtle italic`,children:`No storage locations declared by any installed addon.`}),d.map(e=>s(ie,{type:e.id,displayName:e.displayName,description:e.description,cardinality:e.cardinality,locations:E.get(e.id)??[],onAdd:e=>m(e),onEdit:e=>v(e),onDelete:e=>{T(e)},onSetDefault:e=>S(e),onToggleEnabled:(e,t)=>w(e,t)},e.id))]}),p!==null&&s(ae,{initialType:p,onClose:()=>m(null),onCreated:()=>{e.invalidateQueries({queryKey:[[`storage`,`listLocations`]]}),m(null)}}),h!==null&&s(re,{location:h,onClose:()=>v(null),onSaved:()=>{e.invalidateQueries({queryKey:[[`storage`,`listLocations`]]}),v(null)}})]})}t();var se=[[`backup`,`listDestinations`]],ce=[`backup`,`listArchives`];function le({destinationId:t,restoreSupported:i,onOpenRestoreWizard:c}){let l=a(),u=C(),{data:d,isLoading:f,isError:m}=x({destinationId:t}),h=d??[],g=p({onSuccess:()=>{l.invalidateQueries({queryKey:[[...ce]]}),l.invalidateQueries({queryKey:se})}}),_=e(async e=>{await u({title:`Delete this archive?`,message:`Permanently deletes "${e.label??e.id}" and frees ${V(e.sizeBytes)}.`,confirmLabel:`Delete`,variant:`danger`})&&g.mutate({destinationId:t,backupId:e.id})},[u,t,g]),[v,y]=o(null),b=e(async e=>{y(e.id);try{let n=await te(ue(t,e.id)),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`${e.label??e.id}.tar.gz`,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(r)}finally{y(null)}},[t]),S=r(()=>[...h].toSorted((e,t)=>t.createdAt-e.createdAt),[h]);return f?s(`div`,{className:`text-xs text-foreground-subtle animate-pulse py-2`,children:`Loading archives…`}):m?s(`div`,{className:`text-xs text-danger py-2`,children:`Failed to read manifest for this destination`}):S.length===0?s(`div`,{className:`text-xs text-foreground-subtle italic py-2`,children:`No archives at this destination yet.`}):s(`div`,{className:`rounded border border-border bg-surface overflow-x-auto`,children:n(`table`,{className:`w-full text-xs min-w-[640px]`,children:[s(`thead`,{children:n(`tr`,{className:`text-foreground-subtle bg-background/30`,children:[s(`th`,{className:`text-left px-3 py-1.5 font-medium`,children:`When`}),s(`th`,{className:`text-left px-3 py-1.5 font-medium`,children:`Label`}),s(`th`,{className:`text-left px-3 py-1.5 font-medium`,children:`Includes`}),s(`th`,{className:`text-right px-3 py-1.5 font-medium`,children:`Size`}),s(`th`,{className:`text-right px-3 py-1.5 font-medium w-52`,children:`Actions`})]})}),s(`tbody`,{children:S.map(e=>n(`tr`,{className:`border-t border-border hover:bg-primary/5`,children:[s(`td`,{className:`px-3 py-1.5 text-foreground tabular-nums`,children:Y(e.createdAt)}),s(`td`,{className:`px-3 py-1.5 text-foreground`,children:e.label??s(`span`,{className:`text-foreground-subtle italic`,children:`—`})}),s(`td`,{className:`px-3 py-1.5 text-foreground-subtle`,children:e.locations.join(`, `)}),s(`td`,{className:`px-3 py-1.5 text-foreground text-right tabular-nums`,children:V(e.sizeBytes)}),s(`td`,{className:`px-3 py-1.5`,children:n(`div`,{className:`flex items-center justify-end gap-1`,children:[n(`button`,{onClick:()=>{b(e)},disabled:v===e.id,className:`inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle hover:text-foreground hover:bg-primary/10 disabled:opacity-50`,title:`Download archive`,children:[v===e.id?s(N,{className:`h-3 w-3 animate-spin`}):s(D,{className:`h-3 w-3`}),`Download`]}),i&&c&&n(`button`,{onClick:()=>c({destinationId:t,archiveId:e.id}),className:`inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-primary hover:bg-primary/10`,title:`Restore from this archive`,children:[s(M,{className:`h-3 w-3`}),`Restore`]}),s(`button`,{onClick:()=>{_(e)},disabled:g.isPending,className:`inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-danger hover:bg-danger/10 disabled:opacity-50`,title:`Delete archive`,children:g.isPending?s(N,{className:`h-3 w-3 animate-spin`}):s(z,{className:`h-3 w-3`})})]})})]},e.id))})]})})}function ue(e,t){return`/api/backup/download/${encodeURIComponent(e)}/${encodeURIComponent(t)}`}function Y(e){return new Date(e).toLocaleString(void 0,{day:`2-digit`,month:`short`,year:`numeric`,hour:`2-digit`,minute:`2-digit`})}t();var X=[[`backup`,`listSchedules`]];function de({onEdit:e,onOpenRestoreWizard:t}){let{data:i,isLoading:a,isError:c}=l(),u=i??[],d=h().data??[],f=r(()=>{let e=new Map;for(let t of d)e.set(t.id,t);return e},[d]),[p,m]=o(null),g=e=>{m(t=>t===e?null:e)};return a?s(`div`,{className:`text-xs text-foreground-subtle animate-pulse`,children:`Loading backup entries…`}):c?s(`div`,{className:`text-xs text-danger`,children:`Failed to load backup entries`}):u.length===0?s(`div`,{className:`rounded-lg border border-border bg-surface px-4 py-8 text-center`,children:s(`p`,{className:`text-xs text-foreground-subtle`,children:`No backup entries yet. Create one to schedule backups across one or more storage locations.`})}):s(`div`,{className:`rounded-lg border border-border bg-surface overflow-x-auto`,children:n(`table`,{className:`w-full text-xs min-w-[820px]`,children:[s(`thead`,{children:n(`tr`,{className:`text-foreground-subtle border-b border-border bg-background/40`,children:[s(`th`,{className:`text-left px-3 py-2 font-medium w-6`}),s(`th`,{className:`text-left px-3 py-2 font-medium`,children:`Entry`}),s(`th`,{className:`text-left px-3 py-2 font-medium w-20`,children:`Enabled`}),s(`th`,{className:`text-left px-3 py-2 font-medium`,children:`Locations`}),s(`th`,{className:`text-left px-3 py-2 font-medium w-24`,children:`Retention`}),s(`th`,{className:`text-left px-3 py-2 font-medium w-48`,children:`Schedule`}),s(`th`,{className:`text-right px-3 py-2 font-medium w-52`,children:`Actions`})]})}),s(`tbody`,{children:u.map(n=>s(fe,{row:n,destById:f,isOpen:p===n.id,onToggle:()=>g(n.id),onEdit:()=>e(n),...t?{onOpenRestoreWizard:t}:{}},n.id))})]})})}function fe({row:t,destById:l,isOpen:u,onToggle:d,onEdit:f,onOpenRestoreWizard:p}){let m=a(),h=C(),g=T({onSuccess:()=>{m.invalidateQueries({queryKey:X})}}),_=b({onSuccess:()=>{m.invalidateQueries({queryKey:X})}}),v=w({onSuccess:()=>{m.invalidateQueries({queryKey:[[`backup`,`listArchives`]]}),m.invalidateQueries({queryKey:[[`backup`,`listDestinations`]]})}}),[y,x]=o(String(t.retentionCount));c(()=>{x(String(t.retentionCount))},[t.retentionCount]);let S=r(()=>({id:t.id,label:t.label,cron:t.cron,locationIds:[...t.locationIds],retentionCount:t.retentionCount,...t.dataSources?{dataSources:[...t.dataSources]}:{}}),[t]),E=e(e=>{g.mutate({...S,enabled:e})},[g,S]),D=e(()=>{let e=Number.parseInt(y,10);if(Number.isNaN(e)||e<1){x(String(t.retentionCount));return}e!==t.retentionCount&&g.mutate({...S,enabled:t.enabled,retentionCount:e})},[g,S,y,t.retentionCount,t.enabled]),O=e(()=>{t.locationIds.length!==0&&v.mutate({destinations:[...t.locationIds],...t.dataSources&&t.dataSources.length>0?{locations:[...t.dataSources]}:{},label:t.label,retentionCount:t.retentionCount})},[v,t]),j=e(async()=>{await h({title:`Delete backup entry?`,message:`"${t.label||t.id}" will stop running. Existing archives are kept.`,confirmLabel:`Delete`,variant:`warning`})&&_.mutate({id:t.id})},[h,_,t.id,t.label]),M=t.cron.trim().length>0,F=g.isPending||_.isPending;return n(i,{children:[n(`tr`,{className:`border-t border-border first:border-t-0 hover:bg-primary/5`,children:[s(`td`,{className:`px-2 py-2`,children:s(`button`,{onClick:d,className:`inline-flex items-center justify-center rounded p-1 text-foreground-subtle hover:bg-primary/10 hover:text-foreground`,title:u?`Hide archives`:`Show archives`,children:s(u?I:P,{className:`h-3.5 w-3.5`})})}),s(`td`,{className:`px-3 py-2`,children:n(`button`,{onClick:f,className:`text-left hover:underline focus:outline-none`,children:[s(`div`,{className:`text-foreground font-medium`,children:t.label||`(unnamed)`}),t.lastRunAt!==void 0&&n(`div`,{className:`text-[10px] text-foreground-subtle mt-0.5`,children:[`last run `,new Date(t.lastRunAt).toLocaleString()]})]})}),s(`td`,{className:`px-3 py-2`,children:s(`label`,{className:`inline-flex items-center cursor-pointer`,children:s(`input`,{type:`checkbox`,className:`accent-primary`,checked:t.enabled,disabled:F,onChange:e=>E(e.target.checked)})})}),s(`td`,{className:`px-3 py-2`,children:n(`div`,{className:`flex flex-wrap gap-1`,children:[t.locationIds.length===0&&s(`span`,{className:`text-[11px] text-danger italic`,children:`No locations`}),t.locationIds.map(e=>s(`span`,{className:`inline-flex items-center rounded border border-border bg-background px-1.5 py-0.5 text-[10px] text-foreground`,title:e,children:l.get(e)?.displayName??e},e))]})}),s(`td`,{className:`px-3 py-2`,children:s(`input`,{type:`number`,min:1,max:1e3,value:y,disabled:F,onChange:e=>x(e.target.value),onBlur:D,onKeyDown:e=>{e.key===`Enter`&&e.target.blur(),e.key===`Escape`&&x(String(t.retentionCount))},className:`w-16 rounded border border-border bg-background px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary`})}),s(`td`,{className:`px-3 py-2`,children:n(`button`,{onClick:f,className:`group flex flex-col items-start gap-0.5 text-left`,title:`Edit schedule`,children:[n(`span`,{className:`inline-flex items-center gap-1`,children:[s(q,{className:`h-3 w-3 text-foreground-subtle group-hover:text-foreground`}),s(`span`,{className:`font-mono text-[11px] text-foreground`,children:M?t.cron:`Manual`})]}),M&&t.nextRunAt!==void 0&&n(`span`,{className:`text-[10px] text-foreground-subtle`,children:[`next `,new Date(t.nextRunAt).toLocaleString()]})]})}),s(`td`,{className:`px-3 py-2`,children:n(`div`,{className:`flex items-center justify-end gap-1.5`,children:[n(`button`,{onClick:O,disabled:v.isPending||t.locationIds.length===0,className:`inline-flex items-center gap-1 rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50`,title:`Run this entry now`,children:[v.isPending?s(N,{className:`h-3 w-3 animate-spin`}):s(A,{className:`h-3 w-3`}),`Run now`]}),s(`button`,{onClick:f,className:`inline-flex items-center justify-center rounded border border-border p-1 text-foreground-subtle hover:text-foreground hover:bg-primary/5`,title:`Edit entry`,children:s(k,{className:`h-3 w-3`})}),s(`button`,{onClick:()=>{j()},disabled:F,className:`inline-flex items-center justify-center rounded border border-border p-1 text-foreground-subtle hover:text-danger hover:border-danger/40 disabled:opacity-50`,title:`Delete entry`,children:s(z,{className:`h-3 w-3`})})]})})]}),u&&s(`tr`,{className:`border-t border-border bg-background/30`,children:n(`td`,{colSpan:7,className:`px-4 py-3 space-y-4`,children:[t.locationIds.length===0&&s(`p`,{className:`text-xs text-foreground-subtle italic`,children:`This entry has no locations selected.`}),t.locationIds.map(e=>n(`div`,{className:`space-y-1.5`,children:[s(`div`,{className:`text-[11px] font-medium text-foreground-subtle`,children:l.get(e)?.displayName??e}),s(le,{destinationId:e,restoreSupported:l.get(e)?.restoreSupported??!0,...p?{onOpenRestoreWizard:p}:{}})]},e))]})})]})}t();var Z=[{id:`manual`,label:`Manual only`,cron:``},{id:`hourly`,label:`Every hour`,cron:`0 * * * *`,description:`On the hour`},{id:`every-3h`,label:`Every 3 hours`,cron:`0 */3 * * *`,description:`00:00, 03:00, 06:00, 09:00 …`},{id:`every-6h`,label:`Every 6 hours`,cron:`0 */6 * * *`,description:`00:00, 06:00, 12:00, 18:00`},{id:`daily-3am`,label:`Daily at 03:00`,cron:`0 3 * * *`,description:`Every night at 3 AM`},{id:`weekly-sun`,label:`Weekly Sunday 03:00`,cron:`0 3 * * 0`,description:`Sunday morning at 3 AM`}];function pe(e){let t=e.trim();for(let e of Z)if(e.cron===t)return e.id;return`custom`}function me({value:e,onChange:t,previewCount:r=5,disabled:i=!1}){let a=pe(e),[l,u]=o(a===`custom`);c(()=>{a!==`custom`&&u(!1)},[a]);let d=_e(e,250),f=S({cron:d,count:r},{enabled:d.trim().length>0}),p=f.data??null,m=e=>{u(!1),t(e.cron)},h=l||a===`custom`;return n(`div`,{className:`space-y-3`,children:[n(`div`,{className:`space-y-1`,children:[s(`div`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Schedule preset`}),n(`div`,{className:`flex flex-wrap gap-1.5`,children:[Z.map(e=>s(`button`,{type:`button`,onClick:()=>m(e),disabled:i,className:`rounded border px-2 py-1 text-[11px] transition-colors disabled:opacity-50 `+(!l&&a===e.id?`border-primary bg-primary/10 text-primary`:`border-border bg-background text-foreground-subtle hover:bg-primary/5 hover:text-foreground`),title:e.description??e.label,children:e.label},e.id)),s(`button`,{type:`button`,onClick:()=>{u(!0),e.trim().length===0&&t(`0 3 * * *`)},disabled:i,className:`rounded border px-2 py-1 text-[11px] transition-colors disabled:opacity-50 `+(h?`border-primary bg-primary/10 text-primary`:`border-border bg-background text-foreground-subtle hover:bg-primary/5 hover:text-foreground`),children:`Custom…`})]})]}),h&&n(`div`,{className:`space-y-1`,children:[s(`div`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Cron expression (5-field POSIX)`}),s(`input`,{type:`text`,value:e,onChange:e=>t(e.target.value),disabled:i,placeholder:`0 3 * * *`,spellCheck:!1,className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs font-mono text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary`}),n(`p`,{className:`text-[10px] text-foreground-subtle`,children:[`Format: `,s(`span`,{className:`font-mono`,children:`minute hour day-of-month month day-of-week`}),` · all times server-local`]})]}),s(he,{cron:d,preview:p,loading:f.isFetching})]})}function he({cron:e,preview:t,loading:r}){return r&&t===null?n(`div`,{className:`flex items-center gap-2 rounded border border-border bg-background/40 px-3 py-2 text-[11px] text-foreground-subtle`,children:[s(N,{className:`h-3 w-3 animate-spin`}),`Validating…`]}):t===null?null:t.ok?t.nextRuns.length===0?s(`div`,{className:`rounded border border-border bg-background/40 px-3 py-2 text-[11px] text-foreground-subtle`,children:`No future runs match this expression.`}):n(`div`,{className:`space-y-1`,children:[s(`div`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle`,children:`Next runs`}),s(`ul`,{className:`rounded border border-border bg-background/40 divide-y divide-border`,children:t.nextRuns.map((e,t)=>n(`li`,{className:`flex items-center justify-between px-3 py-1.5 text-[11px]`,children:[s(`span`,{className:`text-foreground tabular-nums`,children:new Date(e).toLocaleString()}),s(`span`,{className:`text-foreground-subtle text-[10px] tabular-nums`,children:ge(e)})]},`${e}-${t}`))})]}):s(`div`,{className:`rounded border border-danger/40 bg-danger/10 px-3 py-2 text-[11px] text-danger`,children:t.error??`Invalid cron expression`})}function ge(e){let t=e-Date.now();if(t<=0)return`now`;let n=Math.floor(t/1e3);if(n<60)return`in ${n}s`;let r=Math.floor(n/60);if(r<60)return`in ${r}m`;let i=Math.floor(r/60);return i<24?`in ${i}h`:`in ${Math.floor(i/24)}d`}function _e(e,t){let[n,i]=o(e),a=r(()=>e,[e]);return c(()=>{let e=setTimeout(()=>i(a),t);return()=>clearTimeout(e)},[a,t]),n}t();var ve=[[`backup`,`listSchedules`]];function ye({entry:e,onClose:t,onSaved:i}){let c=a(),l=h(),u=l.data??[],[d,f]=o(e?.label??``),[p,m]=o(e?.cron??`0 3 * * *`),[g,_]=o(e?.enabled??!0),[v,y]=o(String(e?.retentionCount??7)),[b,x]=o(new Set(e?.locationIds??[])),S=T({onSuccess:()=>{c.invalidateQueries({queryKey:ve}),i()}}),C=e=>{x(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},w=Number.parseInt(v,10),E=r(()=>d.trim().length>0&&b.size>0&&!Number.isNaN(w)&&w>=1&&w<=1e3,[d,b,w]),D=()=>{E&&S.mutate({...e?{id:e.id}:{},label:d.trim(),cron:p.trim(),enabled:g,locationIds:Array.from(b),retentionCount:w})},O=S.error instanceof Error?S.error.message:null;return s(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm`,onClick:t,children:n(`div`,{className:`w-full max-w-lg rounded-xl border border-border bg-surface shadow-2xl max-h-[90vh] overflow-y-auto`,onClick:e=>e.stopPropagation(),children:[n(`div`,{className:`flex items-start justify-between border-b border-border px-4 py-3 sticky top-0 bg-surface`,children:[s(`h2`,{className:`text-sm font-semibold text-foreground`,children:e?`Edit backup entry`:`New backup entry`}),s(`button`,{onClick:t,className:`text-foreground-subtle hover:text-foreground`,children:s(L,{className:`h-4 w-4`})})]}),n(`div`,{className:`p-4 space-y-4`,children:[n(`div`,{className:`space-y-1`,children:[s(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:`Name`}),s(`input`,{type:`text`,value:d,onChange:e=>f(e.target.value),placeholder:`Nightly offsite`,className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary`})]}),n(`div`,{className:`space-y-1.5`,children:[n(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:[`Locations (`,b.size,` selected)`]}),l.isLoading&&n(`div`,{className:`flex items-center gap-2 px-1 py-2 text-xs text-foreground-subtle`,children:[s(N,{className:`h-3.5 w-3.5 animate-spin`}),`Loading locations…`]}),!l.isLoading&&u.length===0&&s(`div`,{className:`rounded border border-border bg-background px-3 py-2 text-xs text-foreground-subtle italic`,children:"No `backups` storage locations configured. Add one in Settings → Storage first."}),u.length>0&&s(`div`,{className:`rounded border border-border bg-background divide-y divide-border max-h-52 overflow-y-auto`,children:u.map(e=>n(`label`,{className:`flex items-center justify-between px-3 py-2 text-xs hover:bg-primary/5 cursor-pointer`,children:[n(`div`,{className:`flex items-center gap-2`,children:[s(`input`,{type:`checkbox`,checked:b.has(e.id),onChange:()=>C(e.id),className:`accent-primary`}),s(`span`,{className:`text-foreground`,children:e.displayName})]}),n(`div`,{className:`flex items-center gap-1.5`,children:[s(`span`,{className:`text-[10px] uppercase tracking-wide text-foreground-subtle bg-surface border border-border rounded px-1.5 py-0.5`,children:e.kind}),s(`span`,{className:`text-[10px] text-foreground-subtle font-mono`,children:e.id})]})]},e.id))})]}),n(`div`,{className:`grid grid-cols-2 gap-3`,children:[n(`div`,{className:`space-y-1`,children:[s(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:`Retention (archives kept)`}),s(`input`,{type:`number`,min:1,max:1e3,value:v,onChange:e=>y(e.target.value),className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary`})]}),n(`div`,{className:`space-y-1`,children:[s(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:`Enabled`}),n(`label`,{className:`inline-flex items-center gap-2 py-1.5 cursor-pointer`,children:[s(`input`,{type:`checkbox`,checked:g,onChange:e=>_(e.target.checked),className:`accent-primary`}),s(`span`,{className:`text-xs text-foreground-subtle`,children:`Run on schedule`})]})]})]}),n(`div`,{className:`space-y-1.5 border-t border-border pt-3`,children:[s(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:`Schedule`}),s(me,{value:p,onChange:m,disabled:S.isPending})]}),O&&s(`div`,{className:`rounded border border-danger/40 bg-danger/10 px-3 py-2 text-[11px] text-danger`,children:O})]}),n(`div`,{className:`flex justify-end gap-2 border-t border-border px-4 py-3 sticky bottom-0 bg-surface`,children:[s(`button`,{onClick:t,className:`rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground`,children:`Cancel`}),n(`button`,{onClick:D,disabled:!E||S.isPending,className:`inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50`,children:[S.isPending&&s(N,{className:`h-3.5 w-3.5 animate-spin`}),e?`Save`:`Create entry`]})]})]})})}t();var be=[[`backup`,`list`]];function xe({initialDestinationId:e,initialArchiveId:t,onClose:i,onScheduled:l}){let u=a(),[d,f]=o(e&&t?2:1),[p,m]=o(e),[g,_]=o(t),[y,b]=o(new Set),{data:S}=h(),C=S??[],{data:w,isLoading:T}=x({destinationId:p??``},{enabled:!!p}),D=w??[];c(()=>{if(p!==void 0)return;let e=C.filter(e=>e.restoreSupported);e.length===1&&m(e[0].id)},[p,C]);let{data:O}=v({destinationId:p??``,backupId:g??``},{enabled:!!p&&!!g}),k=r(()=>O?.locations??[],[O]);c(()=>{k.length!==0&&b(e=>e.size===0?new Set(k):e)},[k]);let A=E({onSuccess:()=>{u.invalidateQueries({queryKey:be}),l(),i()}}),j=e=>{b(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},P=!!p&&!!g,F=y.size>0,I=P&&F&&!A.isPending,R=()=>{!p||!g||A.mutate({destinationId:p,backupId:g,locations:[...y]})};return s(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm`,onClick:i,children:n(`div`,{className:`w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl`,onClick:e=>e.stopPropagation(),children:[n(`div`,{className:`flex items-start justify-between border-b border-border px-4 py-3`,children:[n(`div`,{className:`space-y-0.5`,children:[s(`h2`,{className:`text-sm font-semibold text-foreground`,children:`Restore Backup`}),n(`p`,{className:`text-xs text-foreground-subtle`,children:[`Step `,d,` of 3 —`,` `,d===1?`pick source`:d===2?`pick locations`:`confirm`]})]}),s(`button`,{onClick:i,className:`text-foreground-subtle hover:text-foreground`,children:s(L,{className:`h-4 w-4`})})]}),d===1&&s(Se,{destinations:C,destinationId:p,onPickDestination:e=>{m(e),_(void 0),b(new Set)},archives:D,archivesLoading:T,archiveId:g,onPickArchive:_}),d===2&&s(Ce,{locations:k,picked:y,onToggle:j}),d===3&&s(we,{destinationName:C.find(e=>e.id===p)?.displayName??p??``,archive:D.find(e=>e.id===g),picked:[...y]}),n(`div`,{className:`flex justify-between gap-2 border-t border-border px-4 py-3`,children:[s(`div`,{children:d>1&&n(`button`,{onClick:()=>f(e=>e===3?2:1),className:`inline-flex items-center gap-1 rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground`,children:[s(ee,{className:`h-3 w-3`}),`Back`]})}),n(`div`,{className:`flex items-center gap-2`,children:[s(`button`,{onClick:i,className:`rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground`,children:`Cancel`}),d<3?n(`button`,{disabled:d===1&&!P||d===2&&!F,onClick:()=>f(e=>e===1?2:3),className:`inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50`,children:[`Next`,s(K,{className:`h-3 w-3`})]}):n(`button`,{onClick:R,disabled:!I,className:`inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50`,children:[A.isPending?s(N,{className:`h-3.5 w-3.5 animate-spin`}):s(M,{className:`h-3.5 w-3.5`}),`Schedule Restore`]})]})]})]})})}function Se({destinations:e,destinationId:t,onPickDestination:r,archives:i,archivesLoading:a,archiveId:o,onPickArchive:c}){let l=e.filter(e=>e.restoreSupported);return n(`div`,{className:`p-4 space-y-3`,children:[n(`div`,{className:`space-y-1.5`,children:[s(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:`Destination`}),n(`select`,{value:t??``,onChange:e=>r(e.target.value),className:`w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary`,children:[s(`option`,{value:``,disabled:!0,children:`Select destination…`}),l.map(e=>n(`option`,{value:e.id,children:[e.displayName,` (`,e.kind,`)`]},e.id))]})]}),n(`div`,{className:`space-y-1.5`,children:[s(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:`Archive`}),!t&&s(`div`,{className:`text-xs text-foreground-subtle italic`,children:`Pick a destination first.`}),t&&a&&s(`div`,{className:`text-xs text-foreground-subtle animate-pulse`,children:`Reading archives…`}),t&&!a&&i.length===0&&s(`div`,{className:`text-xs text-foreground-subtle italic`,children:`No archives available at this destination.`}),t&&i.length>0&&s(`div`,{className:`rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto`,children:i.map(e=>{let t=o===e.id;return n(`label`,{className:`flex items-center justify-between px-3 py-2 text-xs cursor-pointer ${t?`bg-primary/10`:`hover:bg-primary/5`}`,children:[n(`div`,{className:`flex items-center gap-2`,children:[s(`input`,{type:`radio`,name:`archive`,checked:t,onChange:()=>c(e.id),className:`accent-primary`}),n(`div`,{children:[s(`div`,{className:`font-medium text-foreground`,children:e.label??e.id}),s(`div`,{className:`text-[10px] text-foreground-subtle`,children:new Date(e.createdAt).toLocaleString()})]})]}),s(`span`,{className:`text-[10px] text-foreground-subtle tabular-nums`,children:V(e.sizeBytes)})]},e.id)})})]})]})}function Ce({locations:e,picked:t,onToggle:r}){return e.length===0?s(`div`,{className:`p-4`,children:s(`div`,{className:`text-xs text-foreground-subtle`,children:`Loading archive manifest… If this persists, the archive may predate manifests — restoring will apply everything in the tarball.`})}):n(`div`,{className:`p-4 space-y-3`,children:[s(`div`,{className:`rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-700 dark:text-amber-300`,children:`Selected entries will overwrite live data on the next server restart. Unchecked entries stay current.`}),n(`div`,{className:`space-y-1.5`,children:[s(`label`,{className:`text-[10px] text-foreground-subtle uppercase tracking-wide`,children:`Apply`}),s(`div`,{className:`rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto`,children:e.map(e=>n(`label`,{className:`flex items-center gap-2 px-3 py-2 text-xs hover:bg-primary/5 cursor-pointer`,children:[s(`input`,{type:`checkbox`,checked:t.has(e),onChange:()=>r(e),className:`accent-primary`}),s(`span`,{className:`font-mono text-foreground`,children:e}),s(`span`,{className:`ml-auto text-[10px] text-foreground-subtle`,children:Ee(e)})]},e))})]})]})}function we({destinationName:e,archive:t,picked:r}){return n(`div`,{className:`p-4 space-y-3 text-xs`,children:[s(`div`,{className:`rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-amber-700 dark:text-amber-300`,children:`Restore is applied at next server boot. Active connections will drop when you restart.`}),n(`dl`,{className:`space-y-1.5`,children:[s(Q,{term:`Destination`,value:e}),s(Q,{term:`Archive`,value:t?.label??t?.id??`—`}),t&&s(Q,{term:`Created`,value:`${new Date(t.createdAt).toLocaleString()} · ${V(t.sizeBytes)}`}),s(Q,{term:`Locations`,value:r.length>0?r.join(`, `):`— (full archive)`})]})]})}function Q({term:e,value:t}){return n(`div`,{className:`flex justify-between gap-3`,children:[s(`dt`,{className:`text-foreground-subtle`,children:e}),s(`dd`,{className:`text-foreground font-mono text-right truncate`,children:t})]})}var Te={db:`Database`,addons:`Addon configs`,"addons-data":`Addon data`,tls:`TLS certificates`,cache:`Cache`,data:`Top-level data`};function Ee(e){return Te[e]??``}t();function De(){let e=C(),t=m(),[r,i]=o(null),[a,c]=o(!1),[l,u]=o(!1),[d,f]=o(void 0),p=async()=>{await e({title:`Restart server now?`,message:`Active connections will drop and the apply-backup hook will run before boot.`,confirmLabel:`Restart`,variant:`warning`})&&t.mutate({confirm:!0})};return n(B,{children:[n(`div`,{className:`flex items-center justify-end gap-2 flex-wrap`,children:[n(`button`,{onClick:()=>c(!0),className:`inline-flex items-center gap-1.5 rounded-lg bg-surface border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-primary/5 hover:border-primary/30`,children:[s(M,{className:`h-3.5 w-3.5`}),`Restore…`]}),n(`button`,{onClick:()=>f(null),className:`inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90`,children:[s(j,{className:`h-3.5 w-3.5`}),`New entry`]})]}),l&&s(`div`,{className:`rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2.5 text-xs text-amber-700 dark:text-amber-300`,children:n(`div`,{className:`flex items-center justify-between gap-3`,children:[n(`div`,{className:`flex items-center gap-2`,children:[s(M,{className:`h-3.5 w-3.5`}),s(`span`,{children:`Restore scheduled. Restart the server to apply.`})]}),n(`button`,{onClick:()=>{p()},disabled:t.isPending,className:`inline-flex items-center gap-1.5 rounded bg-amber-500/20 px-2 py-1 font-medium text-amber-800 dark:text-amber-200 hover:bg-amber-500/30 disabled:opacity-50`,children:[t.isPending?s(N,{className:`h-3.5 w-3.5 animate-spin`}):s(M,{className:`h-3.5 w-3.5`}),`Restart Now`]})]})}),s(de,{onEdit:e=>f(e),onOpenRestoreWizard:e=>i(e)}),d!==void 0&&s(ye,{entry:d,onClose:()=>f(void 0),onSaved:()=>f(void 0)}),(r||a)&&s(xe,{...r?{initialDestinationId:r.destinationId,initialArchiveId:r.archiveId}:{},onClose:()=>{i(null),c(!1)},onScheduled:()=>u(!0)})]})}t();var $=5e3,Oe={"winston-logging":`Rotated log files on this node’s disk.`,"console-logging":`stdout / stderr of the node process.`,"loki-logging":`Pushes to a Grafana Loki instance. Off until enabled with a URL.`,"hub-forwarder":`Agent-only — forwards this node’s entries to the hub.`};function ke(){let e=u({capName:`log-destination`},{refetchInterval:$}),t=d(void 0,{refetchInterval:$}),n=r(()=>W(t.data??[]),[t.data]),i=r(()=>{let e=new Map;for(let n of t.data??[]){let t=n.description,r=n.id;typeof r==`string`&&typeof t==`string`&&t.length>0&&e.set(r,t)}return e},[t.data]);return s(U,{title:`Logging`,subtitle:`Every registered log destination. Entries are fanned to all enabled destinations at once — enabling one does not disable another. Each destination's own configuration is docked under it.`,pageIcon:R,itemIcon:J,capability:`log-destination`,installButtonLabel:`Add destination`,items:r(()=>(e.data??[]).map(e=>({addonId:e.addonId,displayName:n.get(e.addonId)??e.addonId,isActive:e.isActive,caption:i.get(e.addonId)??Oe[e.addonId]??``})),[e.data,n,i]),isLoading:e.isLoading,emptyTitle:`No log destinations registered`,emptyDescription:`This should not happen — the console and rotated-file destinations are builtins. If the list is empty, the node is still booting.`,renderStatusBadges:e=>e.caption.length>0?s(`span`,{className:`text-[10px] text-foreground-subtle`,children:e.caption}):null})}function Ae(){return s(`div`,{className:`flex flex-col p-4`,children:s(ne,{tabs:[{id:`storage`,label:`Storage`,icon:O,content:s(oe,{})},{id:`backup`,label:`Backup`,icon:G,content:s(De,{})},{id:`logging`,label:`Logging`,icon:R,content:s(ke,{})}]})})}export{Ae as DataPage};
|