@hot-updater/console 1.0.0-rc.39 → 1.0.0-rc.40
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/{EventDetails-BUTZTAVo.js → EventDetails-3DgVjwDn.js} +1 -1
- package/.output/public/assets/{InsightsInfo-B8i-PPsH.js → InsightsInfo-NUuLFYqg.js} +1 -1
- package/.output/public/assets/{InsightsPageHeader-CASeYum3.js → InsightsPageHeader-DqCp0vf7.js} +1 -1
- package/.output/public/assets/{index-YSc3HCcR.js → index-B7BSdp0k.js} +2 -2
- package/.output/public/assets/insights-CevVB_8E.js +2 -0
- package/.output/public/assets/insights-DMH-zhbe.js +42 -0
- package/.output/public/assets/insights_.distribution-B9MOEnzZ.js +2 -0
- package/.output/public/assets/insights_.distribution-O73SKvoa.js +1 -0
- package/.output/public/assets/{installations-C-QP0sM1.js → installations-DtZj5jk2.js} +1 -1
- package/.output/public/assets/{installations-yQkxp5fm.js → installations-LJBhFDEM.js} +2 -2
- package/.output/public/assets/{preload-helper-DuV6lz46.js → preload-helper-D9SUwQT7.js} +1 -1
- package/.output/public/assets/{routes-DuBSi7uM.js → routes-CJSxovHS.js} +1 -1
- package/.output/public/assets/routes-DyZCr794.js +2 -0
- package/.output/public/assets/styles-DwA6mhnh.css +2 -0
- package/.output/server/{__23tanstack-start-server-fn-resolver-DNbgEvfb.mjs → __23tanstack-start-server-fn-resolver-CUp7Too4.mjs} +36 -36
- package/.output/server/_ssr/{ConsoleFeatureUnavailable-BCGWklf8.mjs → ConsoleFeatureUnavailable-BxaV7ca0.mjs} +5 -5
- package/.output/server/_ssr/{EventDetails-vtXoqSGS.mjs → EventDetails-B5HHZsCk.mjs} +7 -7
- package/.output/server/_ssr/{InsightsInfo-B0AtaDnr.mjs → InsightsInfo-C7K_HKHZ.mjs} +2 -2
- package/.output/server/_ssr/{InsightsPageHeader-BryzBlT8.mjs → InsightsPageHeader-BPaYzzkg.mjs} +18 -7
- package/.output/server/_ssr/{NotFoundPage-xK1bhpoZ.mjs → NotFoundPage-CyBONH8d.mjs} +2 -2
- package/.output/server/_ssr/{alert-dialog-Cc9d0p8Y.mjs → alert-dialog-BsqgyNOZ.mjs} +1 -1
- package/.output/server/_ssr/{api-keys-C2jqeEZ_.mjs → api-keys-CY1d8bCZ.mjs} +2 -2
- package/.output/server/_ssr/{api-keys-DnKkFZ3T.mjs → api-keys-D8R-eRJ-.mjs} +8 -8
- package/.output/server/_ssr/{api-keys-rpc-BJ0MKu1e.mjs → api-keys-rpc-CC1ERVtk.mjs} +3 -3
- package/.output/server/_ssr/{api-Bz1UGqdn.mjs → api-otC0m2Cl.mjs} +3 -3
- package/.output/server/_ssr/{api-rpc-B9mAeGyS.mjs → api-rpc-C99iexLk.mjs} +4 -4
- package/.output/server/_ssr/{auth-rpc-Bs4tYGIg.mjs → auth-rpc-PABg7kHk.mjs} +4 -4
- package/.output/server/_ssr/{auth.server-CcTNWmd4.mjs → auth.server-8-IRXBc-.mjs} +2 -2
- package/.output/server/_ssr/{card-GK-VihZc.mjs → card-ijGSudc_.mjs} +1 -1
- package/.output/server/_ssr/{config.server-DaeqzKiu.mjs → config.server-08RES1G-.mjs} +3 -3
- package/.output/server/_ssr/{console-access-CSVqeikY.mjs → console-access-D0bQJ9tx.mjs} +2 -2
- package/.output/server/_ssr/{console-features-api-CuukSjL8.mjs → console-features-api-BRGAxAgc.mjs} +3 -3
- package/.output/server/_ssr/{console-features-rpc-Dxv_D020.mjs → console-features-rpc-845alOXy.mjs} +3 -3
- package/.output/server/_ssr/{dialog-Vjm_bDw9.mjs → dialog-BnfVyv4I.mjs} +1 -1
- package/.output/server/_ssr/{empty-DeVHKygf.mjs → empty-CnGZqF1a.mjs} +2 -2
- package/.output/server/_ssr/{failureReports-CRYHdQBQ.mjs → failureReports-_trbWCVo.mjs} +2 -2
- package/.output/server/_ssr/{field-CcbQSAiS.mjs → field-CysUuRJx.mjs} +2 -2
- package/.output/server/_ssr/{input-group-D7oZhqZP.mjs → input-group-C44twsSf.mjs} +1 -1
- package/.output/server/_ssr/{insights-C2_kuG7Z.mjs → insights-Br6JnctH.mjs} +2 -2
- package/.output/server/_ssr/{insights-DFBjq_u1.mjs → insights-CgRV7dlP.mjs} +134 -125
- package/.output/server/_ssr/{insights-CdkhyQHH.mjs → insights-CrrlG-bz.mjs} +5 -5
- package/.output/server/_ssr/{insights-api-CBBcHIUP.mjs → insights-api-MpLvDjmC.mjs} +5 -5
- package/.output/server/_ssr/{insights-errors-F-7hOApm.mjs → insights-errors-Cy03daYs.mjs} +2 -2
- package/.output/server/_ssr/{insights-failures-BZaGNNij.mjs → insights-failures-HHiiIbag.mjs} +4 -5
- package/.output/server/_ssr/{insights-failures-rpc-CTf5QF7O.mjs → insights-failures-rpc-CGiDJbg-.mjs} +8 -8
- package/.output/server/_ssr/{insights-recovery-rpc-CPKwBt4V.mjs → insights-recovery-rpc-Bul_1cyL.mjs} +3 -3
- package/.output/server/_ssr/{insights-rpc-DjhnYd2B.mjs → insights-rpc-D24DKKlx.mjs} +3 -3
- package/.output/server/_ssr/{insights-usage-rpc-CLHRgGDT.mjs → insights-usage-rpc-iG8wRo4G.mjs} +3 -3
- package/.output/server/_ssr/{insights-usage-rpc-CLyldyrz.mjs → insights-usage-rpc-tVCHkzGH.mjs} +3 -3
- package/.output/server/_ssr/{insights_.distribution-DXCwHGBj.mjs → insights_.distribution-Ckc_O360.mjs} +5 -5
- package/.output/server/_ssr/{insights_.distribution-WDmsXtQl.mjs → insights_.distribution-DbO4X6X6.mjs} +2 -2
- package/.output/server/_ssr/{insights_.distribution-Buu3dsat.mjs → insights_.distribution-DsujaomV.mjs} +13 -13
- package/.output/server/_ssr/{installations-BiZY4zjE.mjs → installations-DV3sNoM5.mjs} +10 -10
- package/.output/server/_ssr/{installations-Dfe3WTAY.mjs → installations-DkJq_y8i.mjs} +2 -2
- package/.output/server/_ssr/{installations-sR2BlZxi.mjs → installations-F6vBSPUU.mjs} +4 -4
- package/.output/server/_ssr/{release-adoption-rpc-DVhlhHRR.mjs → release-adoption-rpc-h_r3KQsi.mjs} +5 -5
- package/.output/server/_ssr/{router-HumF5rJs.mjs → router-C_IshN2d.mjs} +13 -13
- package/.output/server/_ssr/{routes-kDK03EWa.mjs → routes-BEHlOXKL.mjs} +33 -22
- package/.output/server/_ssr/{routes-CN0fvuLB.mjs → routes-DeSps20R.mjs} +14 -10
- package/.output/server/_ssr/{select-ycdfR07Y.mjs → select-BL10bGzk.mjs} +1 -1
- package/.output/server/_ssr/{server-CyAnx61_.mjs → server-DIIIVgcN.mjs} +3 -3
- package/.output/server/_ssr/{sidebar-B2SHpuig.mjs → sidebar-DLus-ndm.mjs} +2 -2
- package/.output/server/_ssr/ssr.mjs +1 -1
- package/.output/server/_ssr/{table-COXYXU49.mjs → table-U7InIZlH.mjs} +1 -1
- package/.output/server/_ssr/{updateFailures-BP-A8Ppr.mjs → updateFailures-BLs3R7j0.mjs} +2 -2
- package/.output/server/{_tanstack-start-manifest_v-DcB4oGQp.mjs → _tanstack-start-manifest_v-VxUXUIhM.mjs} +25 -25
- package/.output/server/index.mjs +113 -113
- package/package.json +7 -7
- package/src/components/features/insights/BuiltinBundle.tsx +18 -3
- package/src/components/features/insights/FailureReports.tsx +15 -2
- package/src/components/features/insights/ReleaseActivity.tsx +1 -1
- package/src/components/features/insights/UpdateFailures.tsx +103 -104
- package/src/components/features/releases/ReleaseEditorSheet.tsx +2 -2
- package/src/lib/insights-failures.ts +1 -11
- package/src/routes/index.tsx +33 -15
- package/src/routes/insights.tsx +1 -1
- package/src/routes/insights_.distribution.tsx +3 -3
- package/.output/public/assets/insights-BT0ER2ff.js +0 -2
- package/.output/public/assets/insights-DPY9akyx.js +0 -42
- package/.output/public/assets/insights_.distribution-NyB0_bbh.js +0 -2
- package/.output/public/assets/insights_.distribution-jH_7sKdg.js +0 -1
- package/.output/public/assets/routes-DQWmO9Ow.js +0 -2
- package/.output/public/assets/styles-Cm2ONGCt.css +0 -2
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
failureStageLabel,
|
|
29
29
|
formatRate,
|
|
30
30
|
type InsightsFailureBreakdown,
|
|
31
|
-
patchFallbackRate,
|
|
32
31
|
type UpdateFailuresReport,
|
|
33
32
|
} from "@/lib/insights-failures";
|
|
34
33
|
import { cn } from "@/lib/utils";
|
|
@@ -40,36 +39,65 @@ import { InsightsInfo } from "./InsightsInfo";
|
|
|
40
39
|
const share = (events: number, total: number) =>
|
|
41
40
|
total === 0 ? "—" : `${((events / total) * 100).toFixed(1)}%`;
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
/**
|
|
43
|
+
* One kind of failure: its rate as the headline, then how many failures and
|
|
44
|
+
* installations it holds.
|
|
45
|
+
*/
|
|
46
|
+
function FailureSummary({
|
|
47
|
+
id,
|
|
48
|
+
title,
|
|
45
49
|
info,
|
|
46
|
-
|
|
50
|
+
rate,
|
|
51
|
+
of,
|
|
52
|
+
failures,
|
|
53
|
+
installations,
|
|
54
|
+
previous,
|
|
47
55
|
children,
|
|
48
56
|
}: {
|
|
49
|
-
readonly
|
|
50
|
-
readonly
|
|
51
|
-
readonly
|
|
52
|
-
readonly
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly title: string;
|
|
59
|
+
readonly info: string;
|
|
60
|
+
readonly rate: number | null;
|
|
61
|
+
/** What the rate is a share of. */
|
|
62
|
+
readonly of: string;
|
|
63
|
+
readonly failures: number;
|
|
64
|
+
readonly installations: number;
|
|
65
|
+
readonly previous?: {
|
|
66
|
+
readonly rate: number | null;
|
|
67
|
+
readonly complete: boolean;
|
|
68
|
+
};
|
|
69
|
+
readonly children?: ReactNode;
|
|
53
70
|
}) {
|
|
54
71
|
return (
|
|
55
|
-
<
|
|
56
|
-
<
|
|
57
|
-
{
|
|
58
|
-
|
|
59
|
-
<InsightsInfo label={`About ${label.toLowerCase()}`}>
|
|
60
|
-
{info}
|
|
61
|
-
</InsightsInfo>
|
|
62
|
-
) : null}
|
|
63
|
-
</dt>
|
|
64
|
-
<dd
|
|
65
|
-
className={cn(
|
|
66
|
-
"text-2xl font-semibold tracking-tight tabular-nums",
|
|
67
|
-
attention && "text-warning",
|
|
68
|
-
)}
|
|
72
|
+
<section aria-labelledby={id} className="flex min-w-0 flex-col gap-1">
|
|
73
|
+
<h3
|
|
74
|
+
id={id}
|
|
75
|
+
className="flex min-h-11 items-center gap-1 text-sm font-medium sm:min-h-7"
|
|
69
76
|
>
|
|
70
|
-
{
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
{title}
|
|
78
|
+
<InsightsInfo label={`About ${title.toLowerCase()}`}>
|
|
79
|
+
{info}
|
|
80
|
+
</InsightsInfo>
|
|
81
|
+
</h3>
|
|
82
|
+
<p className="text-3xl font-semibold tracking-tight tabular-nums">
|
|
83
|
+
<Rate value={rate} />
|
|
84
|
+
</p>
|
|
85
|
+
<p className="text-xs text-muted-foreground">{of}</p>
|
|
86
|
+
{previous ? (
|
|
87
|
+
<RateChange
|
|
88
|
+
value={rate}
|
|
89
|
+
previous={previous.rate}
|
|
90
|
+
complete={previous.complete}
|
|
91
|
+
/>
|
|
92
|
+
) : null}
|
|
93
|
+
<p className="mt-2 text-sm text-muted-foreground tabular-nums">
|
|
94
|
+
{failures.toLocaleString()} {failures === 1 ? "failure" : "failures"}
|
|
95
|
+
{" · "}
|
|
96
|
+
<EstimatedCount value={installations} />{" "}
|
|
97
|
+
{installations === 1 ? "installation" : "installations"}
|
|
98
|
+
</p>
|
|
99
|
+
{children}
|
|
100
|
+
</section>
|
|
73
101
|
);
|
|
74
102
|
}
|
|
75
103
|
|
|
@@ -96,13 +124,8 @@ function RateChange({
|
|
|
96
124
|
readonly previous: number | null;
|
|
97
125
|
readonly complete: boolean;
|
|
98
126
|
}) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<span className="mt-1 block text-xs font-normal text-muted-foreground">
|
|
102
|
-
Previous period unavailable
|
|
103
|
-
</span>
|
|
104
|
-
);
|
|
105
|
-
}
|
|
127
|
+
// No change to show before a whole previous period was recorded.
|
|
128
|
+
if (!complete || value === null || previous === null) return null;
|
|
106
129
|
const difference = (value - previous) * 100;
|
|
107
130
|
const rounded = Number(difference.toFixed(2));
|
|
108
131
|
return (
|
|
@@ -198,82 +221,52 @@ function FailuresReport({
|
|
|
198
221
|
}) {
|
|
199
222
|
const breakdown = report.breakdown ?? [];
|
|
200
223
|
const total = breakdown.reduce((sum, { events }) => sum + events, 0);
|
|
224
|
+
const unreasoned = breakdown
|
|
225
|
+
.filter(({ reason }) => reason === "unknown")
|
|
226
|
+
.reduce((sum, { events }) => sum + events, 0);
|
|
227
|
+
const patchAttempts = report.patchDownloads + report.patchFallbacks;
|
|
201
228
|
return (
|
|
202
229
|
<div className="flex flex-col gap-8">
|
|
203
|
-
<div
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
230
|
+
<div className={cn("grid gap-6", report.checks && "sm:grid-cols-2")}>
|
|
231
|
+
<FailureSummary
|
|
232
|
+
id="download-install-failures"
|
|
233
|
+
title="Downloads & installs"
|
|
234
|
+
info="Failed downloads and installs ÷ those plus successful downloads."
|
|
235
|
+
rate={failureRate(report)}
|
|
236
|
+
of="of update attempts failed"
|
|
237
|
+
failures={report.failedUpdates}
|
|
238
|
+
installations={report.failedInstallations}
|
|
239
|
+
previous={
|
|
240
|
+
report.previous && {
|
|
241
|
+
rate: report.previous.attemptRate,
|
|
242
|
+
complete: report.previous.complete,
|
|
243
|
+
}
|
|
244
|
+
}
|
|
209
245
|
>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
label="Attempt failure rate"
|
|
219
|
-
attention={report.failedUpdates > 0}
|
|
220
|
-
info="Share of update attempts that failed: failures ÷ (failures + downloads)."
|
|
221
|
-
>
|
|
222
|
-
<Rate value={failureRate(report)} />
|
|
223
|
-
{report.previous ? (
|
|
224
|
-
<RateChange
|
|
225
|
-
value={failureRate(report)}
|
|
226
|
-
previous={report.previous.attemptRate}
|
|
227
|
-
complete={report.previous.complete}
|
|
228
|
-
/>
|
|
229
|
-
) : null}
|
|
230
|
-
</Metric>
|
|
231
|
-
<Metric
|
|
232
|
-
label="Failed installations"
|
|
233
|
-
attention={report.failedInstallations > 0}
|
|
234
|
-
info="Installations with a failed download or install, estimated within about 3%."
|
|
235
|
-
>
|
|
236
|
-
<EstimatedCount value={report.failedInstallations} />
|
|
237
|
-
</Metric>
|
|
238
|
-
<Metric
|
|
239
|
-
label="Patch fallback rate"
|
|
240
|
-
info="Share of patch downloads that fell back to full files."
|
|
241
|
-
>
|
|
242
|
-
<Rate value={patchFallbackRate(report)} />
|
|
243
|
-
</Metric>
|
|
244
|
-
</dl>
|
|
245
|
-
</section>
|
|
246
|
+
{patchAttempts > 0 ? (
|
|
247
|
+
<p className="text-sm text-muted-foreground tabular-nums">
|
|
248
|
+
{report.patchFallbacks.toLocaleString()} of{" "}
|
|
249
|
+
{patchAttempts.toLocaleString()} patch downloads fell back to the
|
|
250
|
+
full archive
|
|
251
|
+
</p>
|
|
252
|
+
) : null}
|
|
253
|
+
</FailureSummary>
|
|
246
254
|
{report.checks ? (
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
label="Check failure rate"
|
|
263
|
-
attention={report.checks.failedInstallations > 0}
|
|
264
|
-
info="Installations whose update check failed ÷ active installations. Offline checks aren't reported."
|
|
265
|
-
>
|
|
266
|
-
<Rate value={checkFailureRate(report.checks)} />
|
|
267
|
-
{report.previous ? (
|
|
268
|
-
<RateChange
|
|
269
|
-
value={checkFailureRate(report.checks)}
|
|
270
|
-
previous={report.previous.checkRate}
|
|
271
|
-
complete={report.previous.complete}
|
|
272
|
-
/>
|
|
273
|
-
) : null}
|
|
274
|
-
</Metric>
|
|
275
|
-
</dl>
|
|
276
|
-
</section>
|
|
255
|
+
<FailureSummary
|
|
256
|
+
id="update-check-failures"
|
|
257
|
+
title="Update checks"
|
|
258
|
+
info="Installations whose update check failed ÷ active installations. A check that fails offline isn't reported."
|
|
259
|
+
rate={checkFailureRate(report.checks)}
|
|
260
|
+
of="of active installations had a check fail"
|
|
261
|
+
failures={report.checks.failures}
|
|
262
|
+
installations={report.checks.failedInstallations}
|
|
263
|
+
previous={
|
|
264
|
+
report.previous && {
|
|
265
|
+
rate: report.previous.checkRate,
|
|
266
|
+
complete: report.previous.complete,
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/>
|
|
277
270
|
) : null}
|
|
278
271
|
</div>
|
|
279
272
|
<Separator />
|
|
@@ -290,6 +283,12 @@ function FailuresReport({
|
|
|
290
283
|
<h3 className="text-sm font-medium" id="failures-by-stage">
|
|
291
284
|
Failures by stage and reason
|
|
292
285
|
</h3>
|
|
286
|
+
{unreasoned * 2 > total ? (
|
|
287
|
+
<p className="text-sm text-muted-foreground">
|
|
288
|
+
Most report no reason: an SDK that doesn't classify failures
|
|
289
|
+
reports every failed check, offline ones included.
|
|
290
|
+
</p>
|
|
291
|
+
) : null}
|
|
293
292
|
{breakdown.length === 0 ? (
|
|
294
293
|
<p className="text-sm text-muted-foreground">
|
|
295
294
|
No update failures in this period.
|
|
@@ -372,7 +372,7 @@ export function ReleaseEditorSheet({
|
|
|
372
372
|
/>
|
|
373
373
|
{!release.bundle_id ? (
|
|
374
374
|
<span className="text-xs text-foreground">
|
|
375
|
-
Built-in
|
|
375
|
+
Built-in bundle
|
|
376
376
|
</span>
|
|
377
377
|
) : null}
|
|
378
378
|
</span>
|
|
@@ -666,7 +666,7 @@ export function ReleaseEditorSheet({
|
|
|
666
666
|
<div className="sm:col-span-2">
|
|
667
667
|
<dt>Artifact ID</dt>
|
|
668
668
|
<dd className="mt-1 break-all font-mono text-foreground">
|
|
669
|
-
{release.bundle_id ?? "Built-in
|
|
669
|
+
{release.bundle_id ?? "Built-in bundle"}
|
|
670
670
|
</dd>
|
|
671
671
|
</div>
|
|
672
672
|
<div>
|
|
@@ -65,17 +65,6 @@ export const failureRate = ({
|
|
|
65
65
|
? null
|
|
66
66
|
: failedUpdates / (failedUpdates + downloads);
|
|
67
67
|
|
|
68
|
-
/** Of the downloads that tried a patch, the share that fell back to files or the archive. */
|
|
69
|
-
export const patchFallbackRate = ({
|
|
70
|
-
patchDownloads,
|
|
71
|
-
patchFallbacks,
|
|
72
|
-
}: Pick<InsightsUpdateFailures, "patchDownloads" | "patchFallbacks">):
|
|
73
|
-
| number
|
|
74
|
-
| null =>
|
|
75
|
-
patchDownloads + patchFallbacks === 0
|
|
76
|
-
? null
|
|
77
|
-
: patchFallbacks / (patchDownloads + patchFallbacks);
|
|
78
|
-
|
|
79
68
|
/** Installations whose update check failed, over the active ones; estimates, so at most 100%. */
|
|
80
69
|
export const checkFailureRate = ({
|
|
81
70
|
failedInstallations,
|
|
@@ -103,6 +92,7 @@ const REASONS: Readonly<Record<string, string>> = {
|
|
|
103
92
|
patch: "Patch",
|
|
104
93
|
extract: "Extract",
|
|
105
94
|
storage: "Storage",
|
|
95
|
+
unknown: "No reason reported",
|
|
106
96
|
};
|
|
107
97
|
|
|
108
98
|
export const failureStageLabel = (stage: string): string =>
|
package/src/routes/index.tsx
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
Tags,
|
|
14
14
|
X,
|
|
15
15
|
} from "lucide-react";
|
|
16
|
-
import { Fragment, useEffect, useState } from "react";
|
|
16
|
+
import { Fragment, type MouseEvent, useEffect, useState } from "react";
|
|
17
17
|
|
|
18
18
|
import { BundleIdDisplay } from "@/components/BundleIdDisplay";
|
|
19
19
|
import { ChannelBadge } from "@/components/ChannelBadge";
|
|
@@ -84,6 +84,21 @@ const tableDateFormatter = new Intl.DateTimeFormat(undefined, {
|
|
|
84
84
|
dateStyle: "medium",
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Opens a bundle from a click anywhere on its row or card, except on a
|
|
89
|
+
* control inside it, which keeps its own action.
|
|
90
|
+
*/
|
|
91
|
+
const openOutsideControls =
|
|
92
|
+
(open: () => void) => (event: MouseEvent<HTMLElement>) => {
|
|
93
|
+
if (
|
|
94
|
+
event.target instanceof Element &&
|
|
95
|
+
event.target.closest("button, a, input, select, textarea")
|
|
96
|
+
) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
open();
|
|
100
|
+
};
|
|
101
|
+
|
|
87
102
|
export const Route = createFileRoute("/")({
|
|
88
103
|
component: BundlesPage,
|
|
89
104
|
validateSearch: validateReleaseSearch,
|
|
@@ -305,7 +320,7 @@ function BundleEntry({
|
|
|
305
320
|
<BundleIdDisplay bundleId={release.id} fullOnMobile />
|
|
306
321
|
{!release.bundle_id ? (
|
|
307
322
|
<span className="inline-flex items-center gap-1.5 text-sm">
|
|
308
|
-
<RotateCcw className="size-3.5" /> Built-in
|
|
323
|
+
<RotateCcw className="size-3.5" /> Built-in bundle
|
|
309
324
|
</span>
|
|
310
325
|
) : null}
|
|
311
326
|
</button>
|
|
@@ -527,13 +542,24 @@ function BundlesPage() {
|
|
|
527
542
|
|
|
528
543
|
return (
|
|
529
544
|
<Fragment key={release.id}>
|
|
545
|
+
{/* The ID button opens it for keyboards and screen
|
|
546
|
+
readers; a tap anywhere else on the card does too. */}
|
|
530
547
|
<article
|
|
548
|
+
aria-label={`Bundle ${release.id}`}
|
|
531
549
|
className={cn(
|
|
532
|
-
"flex flex-col gap-4 border-b p-4 last:border-b-0",
|
|
550
|
+
"flex cursor-pointer touch-manipulation flex-col gap-4 border-b p-4 transition-[background-color,filter] last:border-b-0 hover:bg-muted/10 active:bg-muted/20 motion-reduce:transition-none data-[state=selected]:bg-muted/15",
|
|
533
551
|
release.currentlyUnreachable &&
|
|
534
|
-
"bg-muted/35 saturate-50
|
|
552
|
+
"bg-muted/35 saturate-50 hover:bg-muted/50 hover:saturate-100 focus-within:saturate-100",
|
|
535
553
|
isExpanded && "border-b-0 bg-primary/5",
|
|
536
554
|
)}
|
|
555
|
+
data-state={
|
|
556
|
+
search.releaseId === release.id
|
|
557
|
+
? "selected"
|
|
558
|
+
: undefined
|
|
559
|
+
}
|
|
560
|
+
onClick={openOutsideControls(() =>
|
|
561
|
+
go({ ...search, releaseId: release.id }, false),
|
|
562
|
+
)}
|
|
537
563
|
>
|
|
538
564
|
<div className="flex items-start justify-between gap-3">
|
|
539
565
|
<BundleEntry
|
|
@@ -703,17 +729,9 @@ function BundlesPage() {
|
|
|
703
729
|
? "selected"
|
|
704
730
|
: undefined
|
|
705
731
|
}
|
|
706
|
-
onClick={(
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
event.target.closest(
|
|
710
|
-
"button, a, input, select, textarea",
|
|
711
|
-
)
|
|
712
|
-
) {
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
go({ ...search, releaseId: release.id }, false);
|
|
716
|
-
}}
|
|
732
|
+
onClick={openOutsideControls(() =>
|
|
733
|
+
go({ ...search, releaseId: release.id }, false),
|
|
734
|
+
)}
|
|
717
735
|
onKeyDown={(event) => {
|
|
718
736
|
if (
|
|
719
737
|
event.target !== event.currentTarget ||
|
package/src/routes/insights.tsx
CHANGED
|
@@ -36,7 +36,7 @@ function InsightsPage() {
|
|
|
36
36
|
const navigate = Route.useNavigate();
|
|
37
37
|
const retention = useInsightsRetention();
|
|
38
38
|
const usageWindow = search.window ?? "24h";
|
|
39
|
-
const bundleWindow = search.bundleWindow ?? "
|
|
39
|
+
const bundleWindow = search.bundleWindow ?? "24h";
|
|
40
40
|
const channel = search.channel ?? search.healthChannel ?? "production";
|
|
41
41
|
const scope: AppUsageScope = {
|
|
42
42
|
platform: search.platform ?? "all",
|
|
@@ -58,7 +58,7 @@ const dates = new Intl.DateTimeFormat("en", {
|
|
|
58
58
|
const bundleName = (row: BundleDistribution): string =>
|
|
59
59
|
row.releaseId ??
|
|
60
60
|
(row.builtinBundleId
|
|
61
|
-
? `Built-in
|
|
61
|
+
? `Built-in bundle ${row.builtinBundleId}`
|
|
62
62
|
: "Unknown bundle");
|
|
63
63
|
|
|
64
64
|
/** The bundle an app version's native build shipped, by its ID. */
|
|
@@ -222,8 +222,8 @@ function DistributionPage() {
|
|
|
222
222
|
<InsightsInfo label="How bundle distribution is counted">
|
|
223
223
|
Each installation counts once, by its latest report{" "}
|
|
224
224
|
{distributionPeriod}. Shares are within each app version.
|
|
225
|
-
Built-in
|
|
226
|
-
Unknown bundle: no deployment and no built-in bundle ID.
|
|
225
|
+
Built-in bundle: the bundle the native build shipped, by its
|
|
226
|
+
ID. Unknown bundle: no deployment and no built-in bundle ID.
|
|
227
227
|
</InsightsInfo>
|
|
228
228
|
</div>
|
|
229
229
|
<div className="flex flex-wrap items-baseline gap-x-3 gap-y-1">
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/insights-BBya_x8N.js","assets/ConsoleFeatureUnavailable-BH7LLqAg.js","assets/sidebar-RBvHzq8e.js","assets/console-features-api-BhUIxeL-.js","assets/empty-DtangHOp.js","assets/NotFoundPage-CkgdpWvl.js","assets/insights-DPY9akyx.js","assets/preload-helper-DuV6lz46.js","assets/alert-dialog-DXxrSU0G.js","assets/mutation-B4EZNS91.js","assets/valueToPercent-Ci2-fmWp.js","assets/useCompositeListItem-BxJspDxS.js","assets/field-bPoDrs6K.js","assets/InsightsPageHeader-CASeYum3.js","assets/card-DKr2pZMA.js","assets/insights-usage-rpc-pz2XQBi3.js","assets/EventDetails-BUTZTAVo.js","assets/input-group-_PD0i7wZ.js","assets/dist-BzWwzt98.js","assets/api-BiZP_i-u.js","assets/refresh-cw-3fSQ1FYY.js","assets/InsightsInfo-B8i-PPsH.js","assets/table-BYmouPt9.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as e}from"./console-features-api-BhUIxeL-.js";import{T as t,t as n,w as r}from"./preload-helper-DuV6lz46.js";import{a as i}from"./InsightsInfo-B8i-PPsH.js";var a=t(`/insights`)({beforeLoad:({context:t})=>e(t.queryClient,`insightsAnalytics`),notFoundComponent:r(()=>n(()=>import(`./insights-BBya_x8N.js`),__vite__mapDeps([0,1,2,3,4,5])),`notFoundComponent`),component:r(()=>n(()=>import(`./insights-DPY9akyx.js`),__vite__mapDeps([6,2,7,3,8,9,10,11,12,13,14,15,16,4,17,18,19,20,21,22])),`component`),validateSearch:i});export{a as t};
|