@hot-updater/console 1.0.0-rc.2 → 1.0.0-rc.21
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/.output/nitro.json +1 -1
- package/.output/public/assets/ConsoleFeatureUnavailable-D0LPL1Gy.js +1 -0
- package/.output/public/assets/HashValueDisplay-BmuB4FW-.js +1 -0
- package/.output/public/assets/InsightsInfo--v4SC07c.js +1 -0
- package/.output/public/assets/InsightsPageHeader-dU83CAQY.js +1 -0
- package/.output/public/assets/NotFoundPage-B5mhGG2a.js +1 -0
- package/.output/public/assets/api-D-vOVlQ4.js +1 -0
- package/.output/public/assets/api-keys-Csh8ARKU.js +1 -0
- package/.output/public/assets/api-keys-OMPUoA_A.js +1 -0
- package/.output/public/assets/arrow-left-Bwq9X1eS.js +1 -0
- package/.output/public/assets/arrow-up-right-BkOVn4if.js +1 -0
- package/.output/public/assets/card-C_7d6O9a.js +1 -0
- package/.output/public/assets/console-features-api-C1jRZTGw.js +1 -0
- package/.output/public/assets/dialog-DE8wFN_P.js +1 -0
- package/.output/public/assets/dist-C7ENGzpS.js +1 -0
- package/.output/public/assets/empty-CVd5NlQD.js +1 -0
- package/.output/public/assets/field-C06q1iC9.js +1 -0
- package/.output/public/assets/index-BeWlQtO6.js +11 -0
- package/.output/public/assets/input-group-Bi61biIA.js +1 -0
- package/.output/public/assets/insights-BjnAtC0f.js +2 -0
- package/.output/public/assets/insights-D86m11yH.js +42 -0
- package/.output/public/assets/insights-DpYstMoY.js +1 -0
- package/.output/public/assets/insights-recovery-rpc-BIm5_ALc.js +1 -0
- package/.output/public/assets/insights-search-KIF7mRtB.js +1 -0
- package/.output/public/assets/insights-usage-rpc-VHj8vyBt.js +1 -0
- package/.output/public/assets/insights_.distribution-ADcrX48c.js +2 -0
- package/.output/public/assets/insights_.distribution-CuuJUN6Y.js +1 -0
- package/.output/public/assets/insights_.distribution-DJRjuXsO.js +1 -0
- package/.output/public/assets/installations-BSBBzqWs.js +2 -0
- package/.output/public/assets/installations-DqIE6WcO.js +1 -0
- package/.output/public/assets/installations-UsELbDvw.js +1 -0
- package/.output/public/assets/loader-circle-CnCBxzHp.js +1 -0
- package/.output/public/assets/mutation-Csp7xUNh.js +1 -0
- package/.output/public/assets/preload-helper-B-cOmpLH.js +1 -0
- package/.output/public/assets/refresh-cw-FF1NtzlQ.js +1 -0
- package/.output/public/assets/routes-CoN9XHP_.js +2 -0
- package/.output/public/assets/routes-DT1jB0Zi.js +1 -0
- package/.output/public/assets/sidebar-D8mJRF15.js +3 -0
- package/.output/public/assets/styles-Bwt7v6U5.css +2 -0
- package/.output/public/assets/table-WBgfvgXg.js +1 -0
- package/.output/public/assets/useCompositeListItem-CloBmDwn.js +1 -0
- package/.output/public/assets/useMutation-DO8cvsTx.js +1 -0
- package/.output/public/assets/useOpenInteractionType-ReGr9GzJ.js +1 -0
- package/.output/public/assets/valueToPercent-BvPAi4bP.js +1 -0
- package/.output/server/{__23tanstack-start-server-fn-resolver-B7ioJhtE.mjs → __23tanstack-start-server-fn-resolver-DMRD4e4f.mjs} +51 -47
- package/.output/server/_libs/@base-ui/react+[...].mjs +7044 -3622
- package/.output/server/_libs/@reduxjs/toolkit+[...].mjs +1554 -0
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +3803 -4023
- package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +141 -98
- package/.output/server/_libs/d3-array.mjs +231 -0
- package/.output/server/_libs/d3-color.mjs +330 -0
- package/.output/server/_libs/d3-format.mjs +252 -0
- package/.output/server/_libs/d3-interpolate.mjs +207 -0
- package/.output/server/_libs/d3-path.mjs +77 -0
- package/.output/server/_libs/d3-scale+[...].mjs +1907 -0
- package/.output/server/_libs/d3-shape.mjs +818 -0
- package/.output/server/_libs/decimal.js-light.mjs +884 -0
- package/.output/server/_libs/es-toolkit.mjs +1159 -0
- package/.output/server/_libs/eventemitter3.mjs +236 -0
- package/.output/server/_libs/immer.mjs +532 -0
- package/.output/server/_libs/lucide-react.mjs +46 -32
- package/.output/server/_libs/next-themes.mjs +2 -2
- package/.output/server/_libs/react-redux+[...].mjs +205 -0
- package/.output/server/_libs/recharts+[...].mjs +14350 -0
- package/.output/server/_libs/sonner.mjs +2 -2
- package/.output/server/_libs/tanstack__history.mjs +68 -41
- package/.output/server/_libs/tanstack__query-core.mjs +1618 -309
- package/.output/server/_libs/tanstack__react-query.mjs +262 -22
- package/.output/server/_libs/verkit.mjs +99 -1
- package/.output/server/_runtime.mjs +10 -1
- package/.output/server/_ssr/ConsoleFeatureUnavailable-Du7jNPNS.mjs +58 -0
- package/.output/server/_ssr/{HashValueDisplay-DwpGLfrl.mjs → HashValueDisplay-GQvFkXoi.mjs} +3 -3
- package/.output/server/_ssr/InsightsInfo-Do7QSaFR.mjs +37 -0
- package/.output/server/_ssr/InsightsPageHeader-DSUWUWRc.mjs +154 -0
- package/.output/server/_ssr/NotFoundPage-DsF4Vrhg.mjs +37 -0
- package/.output/server/_ssr/api-BEiVs0H7.mjs +203 -0
- package/.output/server/_ssr/api-keys-BrvBWGRf.mjs +5 -0
- package/.output/server/_ssr/{api-keys-CZeTPQys.mjs → api-keys-K5v32nf7.mjs} +49 -9
- package/.output/server/_ssr/api-keys-rpc-B96bBllm.mjs +52 -0
- package/.output/server/_ssr/api-rpc-DcUe280B.mjs +296 -0
- package/.output/server/_ssr/{auth-rpc-DUaeOWKK.mjs → auth-rpc-C68W56DP.mjs} +6 -6
- package/.output/server/_ssr/auth.server-DM1J6NwR.mjs +5712 -0
- package/.output/server/_ssr/bundleActivity-CpuY9CTP.mjs +19 -0
- package/.output/server/_ssr/card-CPAEKx0w.mjs +49 -0
- package/.output/server/_ssr/config-nsIcsHh8.mjs +15 -0
- package/.output/server/_ssr/config.server-DDCZk3Sq.mjs +36 -0
- package/.output/server/_ssr/console-access-Da-2Qd7q.mjs +17 -0
- package/.output/server/_ssr/console-features-Dzu2iUGD.mjs +55 -0
- package/.output/server/_ssr/console-features-api-xAsSgFa_.mjs +43 -0
- package/.output/server/_ssr/console-features-rpc-qARGpB24.mjs +19 -0
- package/.output/server/_ssr/{createServerFn-B2hcXoPM.mjs → createMiddleware-BdBf_ezN.mjs} +67 -56
- package/.output/server/_ssr/{createServerRpc-DB29C_5p.mjs → createServerRpc-B_y2lrwA.mjs} +2 -2
- package/.output/server/_ssr/{databaseJsonValue-d6I3nAS4.mjs → databaseJsonValue-Bhxciy7Z.mjs} +28 -5
- package/.output/server/_ssr/databaseRows-DwMAjaF8.mjs +74 -0
- package/.output/server/_ssr/{dialog-DS-nw-pA.mjs → dialog-q__BJ7mQ.mjs} +2 -2
- package/.output/server/_ssr/{dist-CyzPaI5v.mjs → dist-Cxo9ghYv.mjs} +140 -6
- package/.output/server/_ssr/{downloadBundle-CNnYxYO2.mjs → downloadBundle-BW9I-pMQ.mjs} +10 -10
- package/.output/server/_ssr/empty-DcBTAooP.mjs +49 -0
- package/.output/server/_ssr/{empty-plugin-adapters-B5QvGpEl.mjs → empty-plugin-adapters-CYdinE-i.mjs} +1 -1
- package/.output/server/_ssr/{table-CnZmon_Z.mjs → field-QCDBVpXA.mjs} +63 -51
- package/.output/server/_ssr/getBundleChildren-DIAGCF4a.mjs +22 -0
- package/.output/server/_ssr/{input-group-BpsnmvZw.mjs → input-group-hCk2nUoU.mjs} +2 -2
- package/.output/server/_ssr/insights-BfBO0RFr.mjs +1238 -0
- package/.output/server/_ssr/insights-DsAU3-TB.mjs +14 -0
- package/.output/server/_ssr/insights-RIfg447W.mjs +5 -0
- package/.output/server/_ssr/insights-api-CDn-QQHU.mjs +105 -0
- package/.output/server/_ssr/insights-failures-BBGMhuUr.mjs +44 -0
- package/.output/server/_ssr/insights-failures-rpc-rA2dctK2.mjs +21 -0
- package/.output/server/_ssr/insights-recovery-Dpk6Mfb9.mjs +28 -0
- package/.output/server/_ssr/insights-recovery-rpc-BCaF-xSd.mjs +46 -0
- package/.output/server/_ssr/insights-recovery-rpc-CcgYyUHk.mjs +20 -0
- package/.output/server/_ssr/{insights-rpc-38DujK0G.mjs → insights-rpc-keycmwzw.mjs} +22 -14
- package/.output/server/_ssr/insights-search-BRg5VsNe.mjs +25 -0
- package/.output/server/_ssr/insights-usage-cbw9n2Fq.mjs +29 -0
- package/.output/server/_ssr/insights-usage-rpc-BKgV1QDf.mjs +29 -0
- package/.output/server/_ssr/insights-usage-rpc-D-JYachy.mjs +41 -0
- package/.output/server/_ssr/insightsRecovery-B7oMc8d8.mjs +45 -0
- package/.output/server/_ssr/insightsUsage-Oa7kk5ek.mjs +56 -0
- package/.output/server/_ssr/insights_.distribution-BIqOqRW0.mjs +335 -0
- package/.output/server/_ssr/insights_.distribution-CuUrDa7P.mjs +5 -0
- package/.output/server/_ssr/insights_.distribution-RT_6x_ud.mjs +14 -0
- package/.output/server/_ssr/{installations-DiVKEF5T.mjs → installations-BO5CjX2z.mjs} +517 -54
- package/.output/server/_ssr/installations-BjaHiIfh.mjs +5 -0
- package/.output/server/_ssr/installations-Dt5luA-N.mjs +69 -0
- package/.output/server/_ssr/listReleases-BitHzOYB.mjs +79 -0
- package/.output/server/_ssr/releaseManagement-B3e7I8J9.mjs +11 -0
- package/.output/server/_ssr/{router-B9wG_9f8.mjs → router-DfVAixxe.mjs} +135 -139
- package/.output/server/_ssr/{routes-D7Yh_jfj.mjs → routes-C6LstNp8.mjs} +176 -455
- package/.output/server/_ssr/routes-Q3Uhmwwz.mjs +292 -0
- package/.output/server/_ssr/runtime.server-fL0o6I2b.mjs +1459 -0
- package/.output/server/_ssr/schema-BKY9SqaY.mjs +25 -0
- package/.output/server/_ssr/select-CUlInmjk.mjs +107 -0
- package/.output/server/_ssr/server-C43wq9ft.mjs +8330 -0
- package/.output/server/_ssr/{createSsrRpc-DjWNJ0uc.mjs → sidebar-DKbx2ach.mjs} +117 -63
- package/.output/server/_ssr/ssr.mjs +1 -1
- package/.output/server/_ssr/start-BXUOv_n8.mjs +4 -0
- package/.output/server/_ssr/table-NGWV8B-S.mjs +53 -0
- package/.output/server/_ssr/updateFailures-Jwe2Baab.mjs +24 -0
- package/.output/server/_ssr/{uuidv7-D0QFkPL_.mjs → uuidv7-C8bwiZr8.mjs} +2 -2
- package/.output/server/_tanstack-start-manifest_v-WQ5qGn8n.mjs +124 -0
- package/.output/server/index.mjs +267 -162
- package/LICENSE +13 -14
- package/README.md +82 -72
- package/lib/index.d.mts +23 -11
- package/lib/vite-internal.mjs +13 -3
- package/lib/vite.d.mts +2 -0
- package/package.json +14 -14
- package/src/components/AppSidebar.tsx +100 -71
- package/src/components/ConsoleAccessPage.tsx +5 -1
- package/src/components/ConsoleFeatureUnavailable.tsx +80 -0
- package/src/components/NotFoundPage.tsx +7 -7
- package/src/components/features/FeatureSlots.tsx +99 -0
- package/src/components/features/api-keys/apiKeysFeatureUi.tsx +15 -0
- package/src/components/features/bundles/BundleMetadata.tsx +8 -5
- package/src/components/features/bundles/RolloutCohortsDialog.tsx +1 -1
- package/src/components/features/channels/ChannelManagementDialog.tsx +2 -5
- package/src/components/features/insights/AppUsage.tsx +370 -0
- package/src/components/features/insights/EstimatedCount.tsx +18 -0
- package/src/components/features/insights/EventDetails.tsx +117 -37
- package/src/components/features/insights/EventHistoryCard.tsx +112 -26
- package/src/components/features/insights/EventHistoryList.tsx +2 -2
- package/src/components/features/insights/InsightsControls.tsx +265 -102
- package/src/components/features/insights/InsightsErrorAlert.tsx +14 -1
- package/src/components/features/insights/InsightsInfo.tsx +48 -0
- package/src/components/features/insights/InsightsOverview.tsx +176 -173
- package/src/components/features/insights/InsightsPageHeader.tsx +35 -20
- package/src/components/features/insights/InsightsPeriodSelector.tsx +89 -0
- package/src/components/features/insights/InstallationHistoryCard.tsx +52 -10
- package/src/components/features/insights/InstallationMatchesCard.tsx +1 -1
- package/src/components/features/insights/ReleaseActivity.tsx +188 -0
- package/src/components/features/insights/ReportingDevicesSummary.tsx +65 -0
- package/src/components/features/insights/UpdateFailures.tsx +319 -0
- package/src/components/features/insights/insightsFeatureUi.tsx +35 -0
- package/src/components/features/releases/ReleaseEditorSheet.tsx +30 -7
- package/src/components/ui/card.tsx +1 -1
- package/src/components/ui/empty.tsx +101 -0
- package/src/components/ui/scroll-area.tsx +52 -0
- package/src/components/ui/sidebar.tsx +22 -29
- package/src/components/ui/tabs.tsx +81 -0
- package/src/index.ts +26 -19
- package/src/lib/api-keys-api.ts +0 -28
- package/src/lib/api-keys-rpc.ts +27 -38
- package/src/lib/api-rpc.ts +189 -266
- package/src/lib/api.ts +19 -102
- package/src/lib/bundle-activity.ts +31 -0
- package/src/lib/console-access.ts +20 -0
- package/src/lib/console-features-api.ts +68 -0
- package/src/lib/console-features-rpc.ts +13 -0
- package/src/lib/console-features.ts +91 -0
- package/src/lib/insights-api.ts +37 -1
- package/src/lib/insights-failures-rpc.ts +21 -0
- package/src/lib/insights-failures.ts +129 -0
- package/src/lib/insights-recovery-rpc.ts +51 -0
- package/src/lib/insights-recovery.ts +68 -0
- package/src/lib/insights-retention.ts +21 -0
- package/src/lib/insights-rpc.ts +30 -12
- package/src/lib/insights-search.ts +58 -0
- package/src/lib/insights-usage-rpc.ts +29 -0
- package/src/lib/insights-usage.ts +74 -0
- package/src/lib/insights-view.ts +38 -2
- package/src/lib/scroll-restoration.ts +21 -0
- package/src/lib/server/adminInsights.ts +124 -0
- package/src/lib/server/auth.server.ts +13 -5
- package/src/lib/server/bundleActivity.ts +37 -0
- package/src/lib/server/config.server.ts +21 -74
- package/src/lib/server/console-feature-apis.ts +59 -0
- package/src/lib/server/console-runtime.server.ts +82 -38
- package/src/lib/server/downloadBundle.ts +16 -15
- package/src/lib/server/getBundleChildren.ts +31 -122
- package/src/lib/server/insightsRecovery.ts +55 -0
- package/src/lib/server/insightsUsage.ts +63 -0
- package/src/lib/server/listReleases.ts +109 -44
- package/src/lib/server/releaseReachability.ts +8 -7
- package/src/lib/server/runtime.server.ts +120 -31
- package/src/lib/server/updateFailures.ts +31 -0
- package/src/routeTree.gen.ts +44 -44
- package/src/router.tsx +3 -2
- package/src/routes/-installations-search.ts +32 -8
- package/src/routes/-releases-search.ts +76 -29
- package/src/routes/__root.tsx +10 -4
- package/src/routes/api/bundles/$bundleId/download.ts +2 -5
- package/src/routes/api-keys.tsx +5 -2
- package/src/routes/index.tsx +167 -104
- package/src/routes/insights.tsx +100 -59
- package/src/routes/insights_.distribution.tsx +398 -0
- package/src/routes/installations.tsx +98 -41
- package/src/vite-internal.ts +15 -3
- package/src/vite.ts +2 -0
- package/.output/public/assets/HashValueDisplay-CB0Eskit.js +0 -1
- package/.output/public/assets/InsightsPageHeader-Car5LNiZ.js +0 -1
- package/.output/public/assets/api-keys-BzKocqRy.js +0 -1
- package/.output/public/assets/api-keys-api-BHcODB7q.js +0 -1
- package/.output/public/assets/card-Dhr_eFYj.js +0 -1
- package/.output/public/assets/chart-no-axes-combined-Dy4WJv2U.js +0 -1
- package/.output/public/assets/composite-Bp98A0Ld.js +0 -1
- package/.output/public/assets/createServerFn-CA8fs7QD.js +0 -3
- package/.output/public/assets/dialog-CUTrcPlB.js +0 -1
- package/.output/public/assets/dist-C_NydL0e.js +0 -1
- package/.output/public/assets/index-DdAz-CXv.js +0 -10
- package/.output/public/assets/input-group-cSOG4wh_.js +0 -1
- package/.output/public/assets/insights-C0PBSZ-n.js +0 -1
- package/.output/public/assets/installations-CE33wgbY.js +0 -2
- package/.output/public/assets/installations-CStZja8x.js +0 -1
- package/.output/public/assets/lazyRouteComponent-Ccp3bwBY.js +0 -1
- package/.output/public/assets/link-CI8idAUi.js +0 -1
- package/.output/public/assets/loader-circle-BoxLrsOu.js +0 -1
- package/.output/public/assets/preload-helper-CQ36nxok.js +0 -1
- package/.output/public/assets/refresh-cw-Bqc72UZG.js +0 -1
- package/.output/public/assets/routes-DGVXdzpw.js +0 -2
- package/.output/public/assets/routes-DTlwOr8I.js +0 -1
- package/.output/public/assets/shield-check-uK3MHWJZ.js +0 -1
- package/.output/public/assets/signing-CMf4aqDO.js +0 -1
- package/.output/public/assets/styles-BCvbtKsm.css +0 -2
- package/.output/public/assets/table-2vcV89QB.js +0 -1
- package/.output/public/assets/useCompositeListItem-CHLITE_4.js +0 -1
- package/.output/public/assets/x-DCd0j8c6.js +0 -1
- package/.output/server/_ssr/InsightsPageHeader-Df4Brj8u.mjs +0 -484
- package/.output/server/_ssr/api-keys-api-BUPQVSpk.mjs +0 -60
- package/.output/server/_ssr/api-keys-rpc-Cs7tS5_j.mjs +0 -136
- package/.output/server/_ssr/api-rpc-tAupfGQm.mjs +0 -1399
- package/.output/server/_ssr/auth.server-DW71WzsD.mjs +0 -47
- package/.output/server/_ssr/bundle-signing-rpc-BhnBw0-d.mjs +0 -16
- package/.output/server/_ssr/bundle-signing.server-C4NW5mWx.mjs +0 -12
- package/.output/server/_ssr/card-BRiPmi0C.mjs +0 -108
- package/.output/server/_ssr/config-Dv8qLDZ0.mjs +0 -13
- package/.output/server/_ssr/config.server-afDuAwaG.mjs +0 -368
- package/.output/server/_ssr/databaseRows-5bCRTxm-.mjs +0 -126
- package/.output/server/_ssr/deleteBundle-BTGwBgzx.mjs +0 -66
- package/.output/server/_ssr/getBundleChildren-C0vh4ZvE.mjs +0 -50
- package/.output/server/_ssr/insights-BdS364Xu.mjs +0 -460
- package/.output/server/_ssr/insightsContract-fjJDBeEE.mjs +0 -303
- package/.output/server/_ssr/installations-CtA59MQG.mjs +0 -29
- package/.output/server/_ssr/routes-CKrrS2q2.mjs +0 -37
- package/.output/server/_ssr/runtime.server-DacU1TBV.mjs +0 -438
- package/.output/server/_ssr/server-D_C2rMzf.mjs +0 -7468
- package/.output/server/_ssr/signing-Dz1WkZOf.mjs +0 -133
- package/.output/server/_ssr/start-DpViQGnt.mjs +0 -4
- package/.output/server/_tanstack-start-manifest_v-2MjTyxil.mjs +0 -97
- package/src/components/features/insights/InsightsBundleReports.tsx +0 -51
- package/src/components/features/signing/BundleSigningPage.tsx +0 -139
- package/src/lib/bundle-signing-api.ts +0 -14
- package/src/lib/bundle-signing-rpc.ts +0 -16
- package/src/lib/server/bundle-signing.server.ts +0 -23
- package/src/lib/server/deleteBundle.ts +0 -145
- package/src/routes/signing.tsx +0 -37
|
@@ -2,27 +2,48 @@ import {
|
|
|
2
2
|
Activity,
|
|
3
3
|
Check,
|
|
4
4
|
ChevronDown,
|
|
5
|
-
|
|
5
|
+
CircleAlert,
|
|
6
|
+
Download,
|
|
6
7
|
RotateCcw,
|
|
7
8
|
} from "lucide-react";
|
|
8
9
|
import { useEffect, useState } from "react";
|
|
9
10
|
|
|
10
11
|
import { HashValueDisplay } from "@/components/HashValueDisplay";
|
|
11
12
|
import { Badge } from "@/components/ui/badge";
|
|
13
|
+
import { describeFailure } from "@/lib/insights-failures";
|
|
12
14
|
import type { InsightsEventRow } from "@/lib/insights-view";
|
|
13
15
|
|
|
14
16
|
type EventHistoryRow = InsightsEventRow;
|
|
15
17
|
|
|
16
18
|
const eventTypes = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
UPDATE_DOWNLOADED: {
|
|
20
|
+
label: "Downloaded",
|
|
21
|
+
description:
|
|
22
|
+
"Download complete. Waiting for the app to restart and apply it.",
|
|
23
|
+
variant: "default",
|
|
24
|
+
icon: Download,
|
|
25
|
+
},
|
|
26
|
+
UPDATE_APPLIED: {
|
|
27
|
+
label: "Update applied",
|
|
28
|
+
description: "The app started using the downloaded update.",
|
|
21
29
|
variant: "success",
|
|
22
|
-
icon:
|
|
30
|
+
icon: Check,
|
|
31
|
+
},
|
|
32
|
+
RECOVERED: {
|
|
33
|
+
label: "Recovered",
|
|
34
|
+
description: "Recovered from a crashed bundle.",
|
|
35
|
+
variant: "warning",
|
|
36
|
+
icon: RotateCcw,
|
|
37
|
+
},
|
|
38
|
+
UPDATE_FAILED: {
|
|
39
|
+
label: "Update failed",
|
|
40
|
+
description: "An update check, download, or install failed.",
|
|
41
|
+
variant: "destructive",
|
|
42
|
+
icon: CircleAlert,
|
|
23
43
|
},
|
|
24
44
|
UNCHANGED: {
|
|
25
|
-
label: "
|
|
45
|
+
label: "No change",
|
|
46
|
+
description: "No download or apply was reported at this point.",
|
|
26
47
|
variant: "secondary",
|
|
27
48
|
icon: Activity,
|
|
28
49
|
},
|
|
@@ -92,28 +113,63 @@ export function EventTimestamp({
|
|
|
92
113
|
);
|
|
93
114
|
}
|
|
94
115
|
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
const deliveries: Readonly<Record<string, string>> = {
|
|
117
|
+
patch: "A patch delivered it.",
|
|
118
|
+
manifest: "Only the changed files were downloaded.",
|
|
119
|
+
archive: "The full archive was downloaded.",
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/** What the event's report added: where an update failed, how a bundle arrived, why a process exited. */
|
|
123
|
+
const eventNote = (
|
|
124
|
+
event: Pick<
|
|
125
|
+
EventHistoryRow,
|
|
126
|
+
"type" | "failure" | "delivery" | "patchFallback" | "previousProcessExit"
|
|
127
|
+
>,
|
|
128
|
+
): string | null => {
|
|
129
|
+
if (event.type === "UPDATE_FAILED" && event.failure) {
|
|
130
|
+
return describeFailure(event.failure);
|
|
131
|
+
}
|
|
132
|
+
if (event.type === "UPDATE_DOWNLOADED" && event.delivery) {
|
|
133
|
+
const delivered = deliveries[event.delivery] ?? null;
|
|
134
|
+
return event.patchFallback
|
|
135
|
+
? `The patch failed. ${delivered ?? ""}`.trim()
|
|
136
|
+
: delivered;
|
|
137
|
+
}
|
|
138
|
+
if (event.type === "RECOVERED" && event.previousProcessExit) {
|
|
139
|
+
return `The crashed process exited with ${event.previousProcessExit}.`;
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export function EventTypeDetails({
|
|
145
|
+
event,
|
|
97
146
|
}: {
|
|
98
|
-
readonly
|
|
147
|
+
readonly event: Pick<
|
|
148
|
+
EventHistoryRow,
|
|
149
|
+
"type" | "failure" | "delivery" | "patchFallback" | "previousProcessExit"
|
|
150
|
+
>;
|
|
99
151
|
}) {
|
|
100
|
-
const eventType = eventTypes[type];
|
|
152
|
+
const eventType = eventTypes[event.type];
|
|
101
153
|
const Icon = eventType.icon;
|
|
154
|
+
const note = eventNote(event);
|
|
102
155
|
return (
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
156
|
+
<div className="flex min-w-0 flex-col items-start gap-2">
|
|
157
|
+
<Badge
|
|
158
|
+
variant={eventType.variant}
|
|
159
|
+
className="gap-1 whitespace-nowrap [&_svg]:size-3"
|
|
160
|
+
>
|
|
161
|
+
<Icon aria-hidden="true" />
|
|
162
|
+
{eventType.label}
|
|
163
|
+
</Badge>
|
|
164
|
+
<p className="max-w-56 whitespace-normal text-xs text-muted-foreground">
|
|
165
|
+
{event.type === "UPDATE_FAILED" && note ? note : eventType.description}
|
|
166
|
+
</p>
|
|
167
|
+
{event.type !== "UPDATE_FAILED" && note ? (
|
|
168
|
+
<p className="max-w-56 whitespace-normal text-xs text-muted-foreground">
|
|
169
|
+
{note}
|
|
170
|
+
</p>
|
|
171
|
+
) : null}
|
|
172
|
+
</div>
|
|
117
173
|
);
|
|
118
174
|
}
|
|
119
175
|
|
|
@@ -121,14 +177,28 @@ export function EventBundleTransition({
|
|
|
121
177
|
event,
|
|
122
178
|
touch = false,
|
|
123
179
|
}: {
|
|
124
|
-
readonly event: Pick<
|
|
180
|
+
readonly event: Pick<
|
|
181
|
+
EventHistoryRow,
|
|
182
|
+
"type" | "fromBundleId" | "toBundleId" | "failure"
|
|
183
|
+
>;
|
|
125
184
|
readonly touch?: boolean;
|
|
126
185
|
}) {
|
|
186
|
+
const downloaded = event.type === "UPDATE_DOWNLOADED";
|
|
187
|
+
const failed = event.type === "UPDATE_FAILED";
|
|
188
|
+
// A failed check targets no bundle: it names the one running.
|
|
189
|
+
const targeted = !failed || event.failure?.stage !== "check";
|
|
190
|
+
const changed =
|
|
191
|
+
downloaded ||
|
|
192
|
+
failed ||
|
|
193
|
+
event.type === "UPDATE_APPLIED" ||
|
|
194
|
+
event.type === "RECOVERED";
|
|
127
195
|
return (
|
|
128
196
|
<dl className="grid grid-cols-[auto_minmax(0,1fr)] items-center gap-x-2 gap-y-2">
|
|
129
|
-
{event.fromBundleId ? (
|
|
197
|
+
{event.fromBundleId && changed ? (
|
|
130
198
|
<>
|
|
131
|
-
<dt className="text-muted-foreground">
|
|
199
|
+
<dt className="text-muted-foreground">
|
|
200
|
+
{downloaded || failed ? "Running" : "From"}
|
|
201
|
+
</dt>
|
|
132
202
|
<dd>
|
|
133
203
|
<HashValueDisplay
|
|
134
204
|
value={event.fromBundleId}
|
|
@@ -137,15 +207,25 @@ export function EventBundleTransition({
|
|
|
137
207
|
</dd>
|
|
138
208
|
</>
|
|
139
209
|
) : null}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
210
|
+
{targeted ? (
|
|
211
|
+
<>
|
|
212
|
+
<dt className="text-muted-foreground">
|
|
213
|
+
{downloaded
|
|
214
|
+
? "Pending"
|
|
215
|
+
: failed
|
|
216
|
+
? "Target"
|
|
217
|
+
: changed
|
|
218
|
+
? "To"
|
|
219
|
+
: "Current"}
|
|
220
|
+
</dt>
|
|
221
|
+
<dd>
|
|
222
|
+
<HashValueDisplay
|
|
223
|
+
value={event.toBundleId}
|
|
224
|
+
buttonClassName={touch ? "min-h-11 px-3" : undefined}
|
|
225
|
+
/>
|
|
226
|
+
</dd>
|
|
227
|
+
</>
|
|
228
|
+
) : null}
|
|
149
229
|
</dl>
|
|
150
230
|
);
|
|
151
231
|
}
|
|
@@ -4,7 +4,13 @@ import type { ReactNode } from "react";
|
|
|
4
4
|
|
|
5
5
|
import { HashValueDisplay } from "@/components/HashValueDisplay";
|
|
6
6
|
import { Button, buttonVariants } from "@/components/ui/button";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Card,
|
|
9
|
+
CardContent,
|
|
10
|
+
CardDescription,
|
|
11
|
+
CardHeader,
|
|
12
|
+
CardTitle,
|
|
13
|
+
} from "@/components/ui/card";
|
|
8
14
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
9
15
|
import {
|
|
10
16
|
Table,
|
|
@@ -14,23 +20,39 @@ import {
|
|
|
14
20
|
TableHeader,
|
|
15
21
|
TableRow,
|
|
16
22
|
} from "@/components/ui/table";
|
|
17
|
-
import
|
|
23
|
+
import {
|
|
24
|
+
EVENT_RANGES,
|
|
25
|
+
type EventRange,
|
|
26
|
+
eventRanges,
|
|
27
|
+
type InsightsEventRow,
|
|
28
|
+
type InsightsViewPage,
|
|
29
|
+
widerEventRange,
|
|
30
|
+
} from "@/lib/insights-view";
|
|
18
31
|
|
|
19
32
|
import {
|
|
20
33
|
EventBundleTransition,
|
|
21
34
|
EventTimestamp,
|
|
22
|
-
|
|
35
|
+
EventTypeDetails,
|
|
23
36
|
useInsightsTimeFormat,
|
|
24
37
|
} from "./EventDetails";
|
|
25
38
|
import { EventHistoryList } from "./EventHistoryList";
|
|
26
39
|
import { InsightsErrorAlert } from "./InsightsErrorAlert";
|
|
27
40
|
import { InsightsPagination } from "./InsightsPagination";
|
|
41
|
+
import { PeriodSelector } from "./InsightsPeriodSelector";
|
|
28
42
|
|
|
29
43
|
type EventsLocationState = {
|
|
30
44
|
readonly eventsBefore: number;
|
|
31
45
|
readonly eventsCursor?: string;
|
|
46
|
+
readonly eventsRange?: EventRange;
|
|
32
47
|
};
|
|
33
48
|
|
|
49
|
+
/** The ranges within the days raw events are kept, the shortest always. */
|
|
50
|
+
const rangesWithin = (days: number) =>
|
|
51
|
+
EVENT_RANGES.filter(
|
|
52
|
+
(value, position) =>
|
|
53
|
+
position === 0 || eventRanges[value].durationMs <= days * 86_400_000,
|
|
54
|
+
);
|
|
55
|
+
|
|
34
56
|
function EventIdentity({
|
|
35
57
|
event,
|
|
36
58
|
eventsLocation,
|
|
@@ -62,12 +84,17 @@ function EventIdentity({
|
|
|
62
84
|
query: event.installId || undefined,
|
|
63
85
|
installId: event.installId,
|
|
64
86
|
}}
|
|
65
|
-
|
|
87
|
+
state={(previous) => ({
|
|
88
|
+
insightsPagination: {
|
|
89
|
+
eventsBack: previous.insightsPagination?.eventsBack,
|
|
90
|
+
},
|
|
91
|
+
})}
|
|
92
|
+
aria-label={`View history for ${event.userId ?? "anonymous installation"} (${event.installId})`}
|
|
66
93
|
>
|
|
67
94
|
<span
|
|
68
95
|
className={touch ? "min-w-0 text-left wrap-anywhere" : "truncate"}
|
|
69
96
|
>
|
|
70
|
-
{event.userId ??
|
|
97
|
+
{event.userId ?? "Anonymous installation"}
|
|
71
98
|
</span>
|
|
72
99
|
<ArrowUpRight aria-hidden="true" data-icon="inline-end" />
|
|
73
100
|
</Link>
|
|
@@ -82,6 +109,7 @@ function EventIdentity({
|
|
|
82
109
|
|
|
83
110
|
export function EventHistoryCard({
|
|
84
111
|
children,
|
|
112
|
+
description,
|
|
85
113
|
error,
|
|
86
114
|
eventsLocation,
|
|
87
115
|
history,
|
|
@@ -89,11 +117,16 @@ export function EventHistoryCard({
|
|
|
89
117
|
isLoading,
|
|
90
118
|
onNext,
|
|
91
119
|
onPrevious,
|
|
120
|
+
onRangeChange,
|
|
92
121
|
onRefresh,
|
|
93
122
|
pageNumber,
|
|
123
|
+
range,
|
|
124
|
+
rawDays = 90,
|
|
94
125
|
title = "All events",
|
|
95
126
|
}: {
|
|
96
127
|
readonly children?: ReactNode;
|
|
128
|
+
/** One line under the title that says what the list holds. */
|
|
129
|
+
readonly description?: ReactNode;
|
|
97
130
|
readonly error: Error | null;
|
|
98
131
|
readonly eventsLocation: EventsLocationState;
|
|
99
132
|
readonly history: InsightsViewPage<InsightsEventRow> | undefined;
|
|
@@ -101,30 +134,68 @@ export function EventHistoryCard({
|
|
|
101
134
|
readonly isLoading: boolean;
|
|
102
135
|
readonly onNext: () => void;
|
|
103
136
|
readonly onPrevious: () => void;
|
|
137
|
+
/** Lets the list change its range; a list with a fixed window leaves it out. */
|
|
138
|
+
readonly onRangeChange?: (range: EventRange) => void;
|
|
104
139
|
readonly onRefresh: () => void;
|
|
105
140
|
readonly pageNumber: number;
|
|
141
|
+
/** The time range the list reads, named by its empty and end states. */
|
|
142
|
+
readonly range?: EventRange;
|
|
143
|
+
/** How long the server keeps raw events: the longest range offered. */
|
|
144
|
+
readonly rawDays?: number;
|
|
106
145
|
readonly title?: string;
|
|
107
146
|
}) {
|
|
108
147
|
const dateTimeFormat = useInsightsTimeFormat();
|
|
109
148
|
const hasPrevious = pageNumber > 1;
|
|
149
|
+
const ranges = rangesWithin(rawDays);
|
|
150
|
+
const next = range === undefined ? undefined : widerEventRange(range);
|
|
151
|
+
const wider = next !== undefined && ranges.includes(next) ? next : undefined;
|
|
152
|
+
const widen =
|
|
153
|
+
wider !== undefined && onRangeChange ? (
|
|
154
|
+
<Button
|
|
155
|
+
className="h-11 px-3 lg:h-8"
|
|
156
|
+
onClick={() => onRangeChange(wider)}
|
|
157
|
+
type="button"
|
|
158
|
+
variant="outline"
|
|
159
|
+
>
|
|
160
|
+
{`Show the last ${eventRanges[wider].period}`}
|
|
161
|
+
</Button>
|
|
162
|
+
) : null;
|
|
110
163
|
|
|
111
164
|
return (
|
|
112
165
|
<Card className="@container min-w-0 shadow-sm" aria-busy={isFetching}>
|
|
113
166
|
<CardHeader className="gap-4 p-4 sm:p-6">
|
|
114
|
-
<div className="flex flex-
|
|
115
|
-
<
|
|
116
|
-
<
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
className="
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
167
|
+
<div className="flex flex-col gap-1.5">
|
|
168
|
+
<div className="flex flex-wrap items-center justify-between gap-3">
|
|
169
|
+
<CardTitle>
|
|
170
|
+
<h2>{title}</h2>
|
|
171
|
+
</CardTitle>
|
|
172
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
173
|
+
{range !== undefined && onRangeChange ? (
|
|
174
|
+
<PeriodSelector
|
|
175
|
+
label="Time range"
|
|
176
|
+
onPeriodChange={onRangeChange}
|
|
177
|
+
period={range}
|
|
178
|
+
periods={ranges.map((value) => ({
|
|
179
|
+
value,
|
|
180
|
+
name: `Last ${eventRanges[value].period}`,
|
|
181
|
+
}))}
|
|
182
|
+
/>
|
|
183
|
+
) : null}
|
|
184
|
+
<Button
|
|
185
|
+
className="h-11 lg:h-8"
|
|
186
|
+
disabled={isFetching}
|
|
187
|
+
onClick={onRefresh}
|
|
188
|
+
size="lg"
|
|
189
|
+
variant="outline"
|
|
190
|
+
>
|
|
191
|
+
<RefreshCw aria-hidden="true" data-icon="inline-start" />
|
|
192
|
+
Refresh
|
|
193
|
+
</Button>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
{description ? (
|
|
197
|
+
<CardDescription>{description}</CardDescription>
|
|
198
|
+
) : null}
|
|
128
199
|
</div>
|
|
129
200
|
{children}
|
|
130
201
|
</CardHeader>
|
|
@@ -189,7 +260,7 @@ export function EventHistoryCard({
|
|
|
189
260
|
/>
|
|
190
261
|
</TableCell>
|
|
191
262
|
<TableCell>
|
|
192
|
-
<
|
|
263
|
+
<EventTypeDetails event={event} />
|
|
193
264
|
</TableCell>
|
|
194
265
|
<TableCell>
|
|
195
266
|
<EventIdentity
|
|
@@ -218,14 +289,29 @@ export function EventHistoryCard({
|
|
|
218
289
|
</div>
|
|
219
290
|
</>
|
|
220
291
|
) : (
|
|
221
|
-
<div className="px-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
292
|
+
<div className="flex flex-wrap items-center justify-between gap-3 px-4 pb-4 sm:px-6 sm:pb-6">
|
|
293
|
+
<p className="text-sm text-muted-foreground">
|
|
294
|
+
{hasPrevious
|
|
295
|
+
? "No older events in this range."
|
|
296
|
+
: range !== undefined
|
|
297
|
+
? `No events in the last ${eventRanges[range].period}.`
|
|
298
|
+
: title === "All events"
|
|
299
|
+
? "No events recorded yet"
|
|
300
|
+
: "No matching reports in this period"}
|
|
301
|
+
</p>
|
|
302
|
+
{hasPrevious ? null : widen}
|
|
227
303
|
</div>
|
|
228
304
|
)}
|
|
305
|
+
{range !== undefined &&
|
|
306
|
+
history.nextCursor === null &&
|
|
307
|
+
(history.data.length > 0 || hasPrevious) ? (
|
|
308
|
+
<div className="flex flex-wrap items-center justify-between gap-3 border-t px-4 py-3 sm:px-6">
|
|
309
|
+
<p className="text-sm text-muted-foreground">
|
|
310
|
+
Start of range reached
|
|
311
|
+
</p>
|
|
312
|
+
{widen}
|
|
313
|
+
</div>
|
|
314
|
+
) : null}
|
|
229
315
|
{history.data.length > 0 || hasPrevious || history.nextCursor ? (
|
|
230
316
|
<InsightsPagination
|
|
231
317
|
hasPrevious={hasPrevious}
|
|
@@ -5,7 +5,7 @@ import type { InsightsEventRow } from "@/lib/insights-view";
|
|
|
5
5
|
import {
|
|
6
6
|
EventBundleTransition,
|
|
7
7
|
EventTimestamp,
|
|
8
|
-
|
|
8
|
+
EventTypeDetails,
|
|
9
9
|
} from "./EventDetails";
|
|
10
10
|
|
|
11
11
|
export function EventHistoryList<T extends InsightsEventRow>({
|
|
@@ -29,7 +29,7 @@ export function EventHistoryList<T extends InsightsEventRow>({
|
|
|
29
29
|
className="flex min-w-0 flex-col gap-3 px-4 py-4 sm:px-6"
|
|
30
30
|
>
|
|
31
31
|
<div className="flex flex-wrap items-center justify-between gap-x-4 gap-y-1">
|
|
32
|
-
<
|
|
32
|
+
<EventTypeDetails event={event} />
|
|
33
33
|
<div className="text-xs tabular-nums">
|
|
34
34
|
<EventTimestamp
|
|
35
35
|
value={event.receivedAtMs}
|