@hot-updater/console 1.0.0-rc.9 → 1.0.0
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-jB4Loglh.js +1 -0
- package/.output/public/assets/EventDetails-B6yUsyNA.js +1 -0
- package/.output/public/assets/HashValueDisplay-BFX_kY3-.js +1 -0
- package/.output/public/assets/InsightsInfo-BNO0WznZ.js +1 -0
- package/.output/public/assets/InsightsPageHeader-B892oVml.js +1 -0
- package/.output/public/assets/NotFoundPage-DIqCpWa3.js +1 -0
- package/.output/public/assets/alert-dialog-Bbk_4-WJ.js +1 -0
- package/.output/public/assets/api-DCM0wr6O.js +1 -0
- package/.output/public/assets/api-keys-CIO9L_wu.js +1 -0
- package/.output/public/assets/api-keys-DVTL_--f.js +1 -0
- package/.output/public/assets/arrow-left-CnMYpqB7.js +1 -0
- package/.output/public/assets/arrow-up-right-BtffZA6e.js +1 -0
- package/.output/public/assets/chevron-right-BqD5wtFb.js +1 -0
- package/.output/public/assets/clipboard-DS9ucUQL.js +1 -0
- package/.output/public/assets/console-features-api-BH5m_PtQ.js +1 -0
- package/.output/public/assets/dialog-Bqbb7B0N.js +1 -0
- package/.output/public/assets/dist-LxKJB-Vu.js +1 -0
- package/.output/public/assets/empty-CuT2UhFp.js +1 -0
- package/.output/public/assets/field-BBDpjIqu.js +1 -0
- package/.output/public/assets/index-6o51GkFe.js +11 -0
- package/.output/public/assets/input-group-ja_30qaF.js +1 -0
- package/.output/public/assets/insights-CmraDzQh.js +1 -0
- package/.output/public/assets/insights-CxZ2GCYV.js +2 -0
- package/.output/public/assets/insights-api-BigAU9sZ.js +1 -0
- package/.output/public/assets/insights-usage-rpc-DYEhsCKT.js +1 -0
- package/.output/public/assets/insights-vNRCrfnS.js +42 -0
- package/.output/public/assets/insights_.distribution-ChOerfJt.js +1 -0
- package/.output/public/assets/insights_.distribution-D-e4iga8.js +1 -0
- package/.output/public/assets/insights_.distribution-DZtkibX1.js +2 -0
- package/.output/public/assets/installations-BazSJXE0.js +2 -0
- package/.output/public/assets/installations-ClHTqdAO.js +1 -0
- package/.output/public/assets/installations-DpKsBuHi.js +1 -0
- package/.output/public/assets/key-round-wS_SIZ6b.js +1 -0
- package/.output/public/assets/list-CgrYiadM.js +1 -0
- package/.output/public/assets/refresh-cw-BYgoNCco.js +1 -0
- package/.output/public/assets/remote-config-BWwHOkCK.js +1 -0
- package/.output/public/assets/remote-config-Br56BODb.js +6 -0
- package/.output/public/assets/remote-config-CXOi0LRu.js +1 -0
- package/.output/public/assets/routes-B88Erkpk.js +2 -0
- package/.output/public/assets/routes-CfzsAleC.js +1 -0
- package/.output/public/assets/search-DaTDPW25.js +1 -0
- package/.output/public/assets/select-BZZBXMkr.js +1 -0
- package/.output/public/assets/sidebar-DNVyJPfX.js +3 -0
- package/.output/public/assets/smartphone-DpTFgtKf.js +1 -0
- package/.output/public/assets/styles-DTGEAJFv.css +2 -0
- package/.output/public/assets/switch-DZ1TPwx-.js +1 -0
- package/.output/public/assets/table-Gm4qRWwE.js +1 -0
- package/.output/public/assets/tabs-C7FOEjFC.js +1 -0
- package/.output/public/assets/undo-2-CmrHjwFc.js +1 -0
- package/.output/public/assets/useCompositeListItem-9E4pj_CH.js +1 -0
- package/.output/public/assets/valueToPercent-CH8GCHaL.js +1 -0
- package/.output/server/__23tanstack-start-server-fn-resolver-BpRlos5Q.mjs +170 -0
- package/.output/server/_libs/@base-ui/react+[...].mjs +4389 -4207
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +3802 -4022
- package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +140 -97
- package/.output/server/_libs/lucide-react.mjs +221 -9
- package/.output/server/_libs/next-themes.mjs +1 -1
- package/.output/server/_libs/react-redux+[...].mjs +1 -1
- package/.output/server/_libs/recharts+[...].mjs +483 -901
- package/.output/server/_libs/sonner.mjs +1 -1
- package/.output/server/_libs/tanstack__history.mjs +68 -41
- package/.output/server/_libs/tanstack__query-core.mjs +2010 -309
- package/.output/server/_libs/tanstack__react-query.mjs +448 -21
- package/.output/server/_libs/verkit.mjs +102 -1
- package/.output/server/_ssr/BundleIdDisplay-x94o9rlU.mjs +13 -0
- package/.output/server/_ssr/ConsoleFeatureUnavailable-ldW8v8-q.mjs +58 -0
- package/.output/server/_ssr/EventDetails-Q8kfj9Nr.mjs +344 -0
- package/.output/server/_ssr/{HashValueDisplay-CyMmr0O9.mjs → HashValueDisplay-n1GholGS.mjs} +3 -3
- package/.output/server/_ssr/InsightsInfo-DuJFatQO.mjs +75 -0
- package/.output/server/_ssr/InsightsPageHeader-BSUX3Ye9.mjs +145 -0
- package/.output/server/_ssr/NotFoundPage-DZzOOzS3.mjs +37 -0
- package/.output/server/_ssr/{dialog-CKvQ4VIE.mjs → alert-dialog-C43Doa0I.mjs} +6 -83
- package/.output/server/_ssr/{api-keys-CzZ7Ont4.mjs → api-keys-B4sYm8dM.mjs} +48 -9
- package/.output/server/_ssr/api-keys-CEnM9fqG.mjs +5 -0
- package/.output/server/_ssr/api-keys-rpc-BIFuUgMt.mjs +52 -0
- package/.output/server/_ssr/api-oZjRn9tP.mjs +186 -0
- package/.output/server/_ssr/api-rpc-BNiFRRK8.mjs +240 -0
- package/.output/server/_ssr/{auth-BF8mbAgF.mjs → auth-UP0wXs4i.mjs} +1 -1
- package/.output/server/_ssr/{auth-rpc-DH6Bhwcz.mjs → auth-rpc-DnZqYxyq.mjs} +6 -6
- package/.output/server/_ssr/auth.server-DFpyxRDd.mjs +5374 -0
- package/.output/server/_ssr/bundleActivity-M5gzBFNg.mjs +18 -0
- package/.output/server/_ssr/config-WVX4IxSR.mjs +15 -0
- package/.output/server/_ssr/config.server-DskXCAyI.mjs +35 -0
- package/.output/server/_ssr/console-access-BJfAXknd.mjs +17 -0
- package/.output/server/_ssr/console-features-Oz0q20jJ.mjs +61 -0
- package/.output/server/_ssr/console-features-api-C9kiKvaV.mjs +43 -0
- package/.output/server/_ssr/console-features-rpc-P0GL7Z-R.mjs +19 -0
- package/.output/server/_ssr/{createServerFn-B2hcXoPM.mjs → createMiddleware-Cm6Tn0_Y.mjs} +67 -56
- package/.output/server/_ssr/{createServerRpc-DB29C_5p.mjs → createServerRpc-RLR4H-Fn.mjs} +2 -2
- package/.output/server/_ssr/databaseConfig-C5SkAyUy.mjs +5 -0
- package/.output/server/_ssr/{databaseJsonValue-d6I3nAS4.mjs → databaseJsonValue-Csbuzc9Q.mjs} +28 -5
- package/.output/server/_ssr/databaseRows-CPphvbag.mjs +73 -0
- package/.output/server/_ssr/dialog-BbYDMjdC.mjs +84 -0
- package/.output/server/_ssr/{dist-CyzPaI5v.mjs → dist-CbQbBIw-.mjs} +140 -7
- package/.output/server/_ssr/{downloadBundle-CI7JUKvC.mjs → downloadBundle-CZysjmNW.mjs} +10 -10
- package/.output/server/_ssr/empty-CVLGfxuu.mjs +60 -0
- package/.output/server/_ssr/{empty-plugin-adapters-B5QvGpEl.mjs → empty-plugin-adapters-CPtwX8a7.mjs} +1 -1
- package/.output/server/_ssr/failureReports-DKDhVsXA.mjs +33 -0
- package/.output/server/_ssr/field-asw83X0v.mjs +189 -0
- package/.output/server/_ssr/getBundleChildren-Cv9iz1As.mjs +22 -0
- package/.output/server/_ssr/{input-group-BrGSjz4S.mjs → input-group-CuYJHosb.mjs} +2 -2
- package/.output/server/_ssr/insights-B55FG5fm.mjs +14 -0
- package/.output/server/_ssr/insights-CWnHIFUV.mjs +5 -0
- package/.output/server/_ssr/insights-CpLpedFZ.mjs +2315 -0
- package/.output/server/_ssr/insights-api-sjws23WF.mjs +122 -0
- package/.output/server/_ssr/insights-errors-BjnFUyZj.mjs +34 -0
- package/.output/server/_ssr/insights-failures-rpc-BvbWvqNf.mjs +36 -0
- package/.output/server/_ssr/insights-failures-xaa41Buf.mjs +46 -0
- package/.output/server/_ssr/insights-recovery-BWQhiZaF.mjs +28 -0
- package/.output/server/_ssr/insights-recovery-rpc-GiYXdkaY.mjs +32 -0
- package/.output/server/_ssr/{insights-rpc-DDKmIrpV.mjs → insights-rpc-DP_8Rmz4.mjs} +22 -14
- package/.output/server/_ssr/insights-usage-BpBM0U0c.mjs +29 -0
- package/.output/server/_ssr/insights-usage-rpc-BiolgB8e.mjs +29 -0
- package/.output/server/_ssr/insights-usage-rpc-KStL0zOx.mjs +41 -0
- package/.output/server/_ssr/insightsUsage-CzhVjsc8.mjs +56 -0
- package/.output/server/_ssr/insights_.distribution-CVrnbP3R.mjs +7 -0
- package/.output/server/_ssr/insights_.distribution-D2HaNTAA.mjs +16 -0
- package/.output/server/_ssr/{insights_.distribution-cIsU-kHG.mjs → insights_.distribution-DN9pR422.mjs} +50 -22
- package/.output/server/_ssr/installations-BHmbbnH8.mjs +5 -0
- package/.output/server/_ssr/{installations-C5anhyP0.mjs → installations-BSCmFq8Q.mjs} +279 -367
- package/.output/server/_ssr/installations-DD1g__Nc.mjs +69 -0
- package/.output/server/_ssr/listReleases-BfUBlCHo.mjs +79 -0
- package/.output/server/_ssr/plugins-BaD1slHx.mjs +2086 -0
- package/.output/server/_ssr/release-adoption-005tQRpo.mjs +55 -0
- package/.output/server/_ssr/release-adoption-rpc-BsstqxUp.mjs +41 -0
- package/.output/server/_ssr/releaseAdoption-CtOFkwli.mjs +114 -0
- package/.output/server/_ssr/releaseManagement-DFMUnDF5.mjs +11 -0
- package/.output/server/_ssr/remote-config-C2Ee8lXO.mjs +5 -0
- package/.output/server/_ssr/remote-config-Dv1ccMo-.mjs +17 -0
- package/.output/server/_ssr/remote-config-of0lGQH8.mjs +2648 -0
- package/.output/server/_ssr/remote-config-rpc-BzX31mUS.mjs +115 -0
- package/.output/server/_ssr/rolldown-runtime-rSIU-vHC.mjs +13 -0
- package/.output/server/_ssr/{router-BuanSsRI.mjs → router-D8NuoJ_I.mjs} +107 -134
- package/.output/server/_ssr/{routes-DY-vqU6R.mjs → routes-DgvnFqDy.mjs} +195 -429
- package/.output/server/_ssr/routes-V8sDybGf.mjs +409 -0
- package/.output/server/_ssr/runtime.server-De0QVWc9.mjs +104 -0
- package/.output/server/_ssr/schema-BiAVyEj2.mjs +361 -0
- package/.output/server/_ssr/{select-DD2szs3Y.mjs → select-t3iXRwc9.mjs} +3 -3
- package/.output/server/_ssr/server-h4VxnExB.mjs +8325 -0
- package/.output/server/_ssr/{createSsrRpc-CdlfejmI.mjs → sidebar-DJcErBMo.mjs} +107 -47
- package/.output/server/_ssr/ssr.mjs +1 -1
- package/.output/server/_ssr/start-BfFbHKMK.mjs +4 -0
- package/.output/server/_ssr/switch-E-btwMGt.mjs +43 -0
- package/.output/server/_ssr/{table-CTj6n-4F.mjs → table-37Dd23TN.mjs} +2 -2
- package/.output/server/_ssr/tabs-DEFnTm95.mjs +45 -0
- package/.output/server/_ssr/updateFailures-H6pnnYK4.mjs +40 -0
- package/.output/server/_ssr/{uuidv7-D0QFkPL_.mjs → uuidv7-C88s9jWF.mjs} +2 -2
- package/.output/server/_tanstack-start-manifest_v-55AGsehh.mjs +139 -0
- package/.output/server/index.mjs +309 -211
- package/LICENSE +13 -14
- package/README.md +80 -71
- 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 +69 -74
- package/src/components/ConsoleFeatureUnavailable.tsx +80 -0
- package/src/components/NotFoundPage.tsx +7 -7
- package/src/components/features/FeatureSlots.tsx +103 -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 +8 -6
- package/src/components/features/insights/AppUsage.tsx +41 -14
- package/src/components/features/insights/BuiltinBundle.tsx +36 -0
- package/src/components/features/insights/ComparedBundlesChart.tsx +310 -0
- package/src/components/features/insights/EstimatedCount.tsx +18 -0
- package/src/components/features/insights/EventDetails.tsx +390 -26
- package/src/components/features/insights/EventHistoryCard.tsx +111 -25
- package/src/components/features/insights/EventHistoryList.tsx +1 -1
- package/src/components/features/insights/FailureReports.tsx +407 -0
- package/src/components/features/insights/InsightsControls.tsx +240 -142
- package/src/components/features/insights/InsightsErrorAlert.tsx +14 -1
- package/src/components/features/insights/InsightsOverview.tsx +601 -403
- package/src/components/features/insights/InsightsPageHeader.tsx +19 -14
- package/src/components/features/insights/InsightsPeriodSelector.tsx +67 -12
- package/src/components/features/insights/InstallationHistoryCard.tsx +65 -10
- package/src/components/features/insights/InstallationMatchesCard.tsx +1 -1
- package/src/components/features/insights/ReleaseActivity.tsx +308 -0
- package/src/components/features/insights/ReportingDevicesSummary.tsx +13 -13
- package/src/components/features/insights/RollbackButton.tsx +118 -0
- package/src/components/features/insights/UpdateFailures.tsx +382 -0
- package/src/components/features/insights/insightsFeatureUi.tsx +35 -0
- package/src/components/features/releases/ReleaseEditorSheet.tsx +27 -13
- package/src/components/features/remote-config/ConditionDialog.tsx +592 -0
- package/src/components/features/remote-config/ConditionsCard.tsx +247 -0
- package/src/components/features/remote-config/ParameterDialog.tsx +426 -0
- package/src/components/features/remote-config/ParametersCard.tsx +254 -0
- package/src/components/features/remote-config/PreviewCard.tsx +284 -0
- package/src/components/features/remote-config/PublishDialog.tsx +325 -0
- package/src/components/features/remote-config/RemoteConfigPage.tsx +353 -0
- package/src/components/features/remote-config/RuleSummary.tsx +21 -0
- package/src/components/features/remote-config/ValueInput.tsx +151 -0
- package/src/components/features/remote-config/VersionsCard.tsx +384 -0
- package/src/components/features/remote-config/remoteConfigFeatureUi.tsx +15 -0
- package/src/components/features/remote-config/useDateTimeText.ts +16 -0
- package/src/components/ui/sidebar.tsx +22 -29
- 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 +125 -288
- package/src/lib/api.ts +15 -134
- package/src/lib/bundle-activity.ts +24 -4
- 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 +98 -0
- package/src/lib/insights-api.ts +56 -2
- package/src/lib/insights-errors.ts +64 -0
- package/src/lib/insights-failures-rpc.ts +36 -0
- package/src/lib/insights-failures.ts +130 -0
- package/src/lib/insights-recovery-rpc.ts +13 -17
- package/src/lib/insights-recovery.ts +12 -36
- package/src/lib/insights-retention.ts +21 -0
- package/src/lib/insights-rpc.ts +30 -12
- package/src/lib/insights-search.ts +50 -4
- package/src/lib/insights-usage-rpc.ts +15 -9
- package/src/lib/insights-usage.ts +41 -3
- package/src/lib/insights-view.ts +34 -5
- package/src/lib/release-adoption-api.ts +214 -0
- package/src/lib/release-adoption-rpc.ts +49 -0
- package/src/lib/release-adoption.ts +164 -0
- package/src/lib/remote-config-api.ts +119 -0
- package/src/lib/remote-config-draft.ts +666 -0
- package/src/lib/remote-config-rpc.ts +196 -0
- package/src/lib/scroll-restoration.ts +21 -0
- package/src/lib/server/auth.server.ts +13 -5
- package/src/lib/server/bundleActivity.ts +27 -28
- package/src/lib/server/config.server.ts +21 -76
- package/src/lib/server/console-feature-apis.ts +70 -0
- package/src/lib/server/console-runtime.server.ts +82 -38
- package/src/lib/server/downloadBundle.ts +14 -15
- package/src/lib/server/failureReports.ts +50 -0
- package/src/lib/server/getBundleChildren.ts +31 -122
- package/src/lib/server/insightsUsage.ts +52 -113
- package/src/lib/server/listReleases.ts +109 -44
- package/src/lib/server/releaseAdoption.ts +151 -0
- package/src/lib/server/releaseReachability.ts +8 -8
- package/src/lib/server/remoteConfig.ts +75 -0
- package/src/lib/server/runtime.server.ts +120 -31
- package/src/lib/server/updateFailures.ts +66 -0
- package/src/lib/use-dialog-target.ts +27 -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 +7 -1
- package/src/routes/api/bundles/$bundleId/download.ts +2 -5
- package/src/routes/api-keys.tsx +5 -2
- package/src/routes/index.tsx +210 -152
- package/src/routes/insights.tsx +91 -23
- package/src/routes/insights_.distribution.tsx +50 -9
- package/src/routes/installations.tsx +97 -40
- package/src/routes/remote-config.tsx +42 -0
- package/src/styles.css +9 -0
- package/src/vite-internal.ts +15 -3
- package/src/vite.ts +2 -0
- package/.output/public/assets/HashValueDisplay-BpTc3Oyg.js +0 -1
- package/.output/public/assets/InsightsPageHeader-DC2eEst8.js +0 -1
- package/.output/public/assets/api-CdUyUqzR.js +0 -42
- package/.output/public/assets/api-keys-64PM9PwW.js +0 -1
- package/.output/public/assets/api-keys-api-BeaJnvY5.js +0 -1
- package/.output/public/assets/arrow-left-04Rh8Zgp.js +0 -1
- package/.output/public/assets/card-CYHs5FZv.js +0 -1
- package/.output/public/assets/chart-no-axes-combined-DwyMsVFW.js +0 -1
- package/.output/public/assets/createServerFn-DU71xucx.js +0 -3
- package/.output/public/assets/dialog-IVMkBRCq.js +0 -1
- package/.output/public/assets/dist-BR4GzeEu.js +0 -1
- package/.output/public/assets/field-B3CYDpjg.js +0 -1
- package/.output/public/assets/index-Cb_D1D6N.js +0 -10
- package/.output/public/assets/info-C3y9HNoU.js +0 -1
- package/.output/public/assets/input-group-nLZylhWF.js +0 -1
- package/.output/public/assets/insights-Bm9v8uO3.js +0 -2
- package/.output/public/assets/insights-DS3iO7Up.js +0 -1
- package/.output/public/assets/insights-search-Byj3g3Mp.js +0 -1
- package/.output/public/assets/insights-usage-rpc-BaGR3lgq.js +0 -1
- package/.output/public/assets/insights_.distribution-B1i6cjlQ.js +0 -1
- package/.output/public/assets/insights_.distribution-C1Wf27eB.js +0 -2
- package/.output/public/assets/installations-CkFW4fV9.js +0 -2
- package/.output/public/assets/installations-DxTaIcHD.js +0 -1
- package/.output/public/assets/lazyRouteComponent-BapzjYnb.js +0 -1
- package/.output/public/assets/list-Dqt53fWZ.js +0 -1
- package/.output/public/assets/loader-circle-CUKfUqow.js +0 -1
- package/.output/public/assets/preload-helper-ClBMtM1g.js +0 -1
- package/.output/public/assets/refresh-cw-CNE_2PnD.js +0 -1
- package/.output/public/assets/routes-Cgtvspjg.js +0 -2
- package/.output/public/assets/routes-O2r2UUN8.js +0 -1
- package/.output/public/assets/shield-check-BFcJ46kz.js +0 -1
- package/.output/public/assets/signing-BgspC-xP.js +0 -1
- package/.output/public/assets/styles-DnrWuBwd.css +0 -2
- package/.output/public/assets/table-BuWQgxJJ.js +0 -1
- package/.output/public/assets/useMutation-CSV9NCUl.js +0 -1
- package/.output/public/assets/useOpenInteractionType-D5kduCTD.js +0 -1
- package/.output/public/assets/valueToPercent-BAtcbSLk.js +0 -1
- package/.output/server/__23tanstack-start-server-fn-resolver-DBRojHaG.mjs +0 -150
- package/.output/server/_ssr/InsightsPageHeader-mtxVuZKK.mjs +0 -64
- package/.output/server/_ssr/api-BfCgYlj5.mjs +0 -332
- package/.output/server/_ssr/api-keys-api-C3oeq01R.mjs +0 -60
- package/.output/server/_ssr/api-keys-rpc-CdPFdGOx.mjs +0 -136
- package/.output/server/_ssr/api-rpc-B2E1ZIG5.mjs +0 -1399
- package/.output/server/_ssr/auth.server-CmicHh0J.mjs +0 -47
- package/.output/server/_ssr/bundle-signing-rpc-Di7-I6fE.mjs +0 -16
- package/.output/server/_ssr/bundle-signing.server-Uqt1OF49.mjs +0 -12
- package/.output/server/_ssr/bundleActivity-pBrPSG01.mjs +0 -28
- package/.output/server/_ssr/card-Bemj0dpY.mjs +0 -108
- package/.output/server/_ssr/config-Dv8qLDZ0.mjs +0 -13
- package/.output/server/_ssr/config.server-B8WsT3s0.mjs +0 -368
- package/.output/server/_ssr/databaseRows-5bCRTxm-.mjs +0 -126
- package/.output/server/_ssr/deleteBundle-8X-jq7Z7.mjs +0 -66
- package/.output/server/_ssr/field-BrQ2u0fT.mjs +0 -74
- package/.output/server/_ssr/getBundleChildren-DoL8l_AS.mjs +0 -50
- package/.output/server/_ssr/insights-BwQ-wF2a.mjs +0 -10
- package/.output/server/_ssr/insights-gr1I_dJU.mjs +0 -938
- package/.output/server/_ssr/insights-recovery-Cv6RSyeR.mjs +0 -21
- package/.output/server/_ssr/insights-recovery-rpc-DOzxfYfv.mjs +0 -37
- package/.output/server/_ssr/insights-search-1czJMZgk.mjs +0 -21
- package/.output/server/_ssr/insights-usage-rpc-4ImOq_0p.mjs +0 -184
- package/.output/server/_ssr/insights-usage-rpc-BUruODjE.mjs +0 -24
- package/.output/server/_ssr/insightsContract-B09K_Px1.mjs +0 -303
- package/.output/server/_ssr/insightsHistory-Ci4rYAgl.mjs +0 -41
- package/.output/server/_ssr/insightsRecovery-CaghWL2t.mjs +0 -113
- package/.output/server/_ssr/insightsUsage-DNIj6jxF.mjs +0 -71
- package/.output/server/_ssr/insights_.distribution-VmHuikRE.mjs +0 -10
- package/.output/server/_ssr/installations-HXMF_kKf.mjs +0 -29
- package/.output/server/_ssr/routes-Dru3IRj0.mjs +0 -37
- package/.output/server/_ssr/runtime.server-CsiKFp_Z.mjs +0 -436
- package/.output/server/_ssr/server-DJm72Kj-.mjs +0 -7468
- package/.output/server/_ssr/signing-H8Lg4lPe.mjs +0 -133
- package/.output/server/_ssr/start-DpViQGnt.mjs +0 -4
- package/.output/server/_tanstack-start-manifest_v-DsFcTLw_.mjs +0 -125
- package/src/components/features/bundles/BundleActivityChart.tsx +0 -97
- package/src/components/features/bundles/BundleInsightsSummary.tsx +0 -126
- 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/lib/server/insightsHistory.ts +0 -52
- package/src/lib/server/insightsRecovery.ts +0 -187
- package/src/routes/signing.tsx +0 -37
package/src/routes/index.tsx
CHANGED
|
@@ -13,14 +13,14 @@ 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";
|
|
20
20
|
import { EnabledStatusIcon } from "@/components/EnabledStatusIcon";
|
|
21
21
|
import { BundleChildrenPanel } from "@/components/features/bundles/BundleChildrenPanel";
|
|
22
|
-
import { BundleMovementSummary } from "@/components/features/bundles/BundleInsightsSummary";
|
|
23
22
|
import { ChannelManagementDialog } from "@/components/features/channels/ChannelManagementDialog";
|
|
23
|
+
import { useReleaseColumns } from "@/components/features/FeatureSlots";
|
|
24
24
|
import { ReleaseEditorSheet } from "@/components/features/releases/ReleaseEditorSheet";
|
|
25
25
|
import { ReleaseStateBadge } from "@/components/features/releases/ReleaseStateBadge";
|
|
26
26
|
import { HashValueDisplay } from "@/components/HashValueDisplay";
|
|
@@ -29,7 +29,6 @@ import { RolloutPercentageBadge } from "@/components/RolloutPercentageBadge";
|
|
|
29
29
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
|
30
30
|
import { Badge } from "@/components/ui/badge";
|
|
31
31
|
import { Button, buttonVariants } from "@/components/ui/button";
|
|
32
|
-
import { Input } from "@/components/ui/input";
|
|
33
32
|
import {
|
|
34
33
|
Select,
|
|
35
34
|
SelectContent,
|
|
@@ -56,11 +55,12 @@ import {
|
|
|
56
55
|
useChannelsQuery,
|
|
57
56
|
useReleasesQuery,
|
|
58
57
|
} from "@/lib/api";
|
|
59
|
-
import { useBundleActivityQuery } from "@/lib/bundle-activity";
|
|
60
58
|
import type { ReleaseListRow } from "@/lib/server/releaseReachability";
|
|
61
59
|
import { cn } from "@/lib/utils";
|
|
62
60
|
|
|
63
61
|
import {
|
|
62
|
+
hasReleaseFilters,
|
|
63
|
+
releaseFilterOf,
|
|
64
64
|
type ReleaseSearch,
|
|
65
65
|
updateReleaseFilters,
|
|
66
66
|
validateReleaseSearch,
|
|
@@ -68,10 +68,14 @@ import {
|
|
|
68
68
|
|
|
69
69
|
const PAGE_SIZE = 20;
|
|
70
70
|
const platformFilterItems = [
|
|
71
|
-
{ label: "All Platforms", value: "all" },
|
|
72
71
|
{ label: "iOS", value: "ios" },
|
|
73
72
|
{ label: "Android", value: "android" },
|
|
74
73
|
];
|
|
74
|
+
const statusFilterItems = [
|
|
75
|
+
{ label: "Any Status", value: "all" },
|
|
76
|
+
{ label: "Enabled", value: "enabled" },
|
|
77
|
+
{ label: "Disabled", value: "disabled" },
|
|
78
|
+
];
|
|
75
79
|
const dateFormatter = new Intl.DateTimeFormat(undefined, {
|
|
76
80
|
dateStyle: "medium",
|
|
77
81
|
timeStyle: "short",
|
|
@@ -80,6 +84,21 @@ const tableDateFormatter = new Intl.DateTimeFormat(undefined, {
|
|
|
80
84
|
dateStyle: "medium",
|
|
81
85
|
});
|
|
82
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
|
+
|
|
83
102
|
export const Route = createFileRoute("/")({
|
|
84
103
|
component: BundlesPage,
|
|
85
104
|
validateSearch: validateReleaseSearch,
|
|
@@ -98,16 +117,9 @@ function BundleFilterToolbar({
|
|
|
98
117
|
onManageChannels: () => void;
|
|
99
118
|
search: ReleaseSearch;
|
|
100
119
|
}) {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const hasFilters = Boolean(
|
|
105
|
-
search.bundleId ||
|
|
106
|
-
search.channelId ||
|
|
107
|
-
search.enabled !== undefined ||
|
|
108
|
-
search.platform ||
|
|
109
|
-
search.targetAppVersion,
|
|
110
|
-
);
|
|
120
|
+
const hasFilters = hasReleaseFilters(search);
|
|
121
|
+
// Releases list by channel and platform together: the index serves that pair.
|
|
122
|
+
const channelSelected = search.channelId !== undefined;
|
|
111
123
|
const channelFilterItems = [
|
|
112
124
|
{ label: "All Channels", value: "all" },
|
|
113
125
|
...channels.map((channel) => ({
|
|
@@ -115,14 +127,6 @@ function BundleFilterToolbar({
|
|
|
115
127
|
value: channel.id,
|
|
116
128
|
})),
|
|
117
129
|
];
|
|
118
|
-
const applyTargetAppVersion = () => {
|
|
119
|
-
const value = targetAppVersion.trim();
|
|
120
|
-
onChange({ targetAppVersion: value || undefined });
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
useEffect(() => {
|
|
124
|
-
setTargetAppVersion(search.targetAppVersion ?? "");
|
|
125
|
-
}, [search.targetAppVersion]);
|
|
126
130
|
|
|
127
131
|
return (
|
|
128
132
|
<header className="sticky top-0 z-10 flex shrink-0 flex-wrap items-center gap-2 border-b bg-background px-3 py-3 sm:h-12 sm:flex-nowrap sm:bg-card/70 sm:px-4 sm:py-0 sm:backdrop-blur-sm">
|
|
@@ -133,65 +137,85 @@ function BundleFilterToolbar({
|
|
|
133
137
|
<span className="text-xs font-medium">Filters</span>
|
|
134
138
|
</div>
|
|
135
139
|
<Select
|
|
136
|
-
items={
|
|
140
|
+
items={channelFilterItems}
|
|
137
141
|
onValueChange={(value) =>
|
|
138
142
|
onChange({
|
|
139
|
-
|
|
140
|
-
value === "all" ? undefined : (value as "ios" | "android"),
|
|
143
|
+
channelId: value === null || value === "all" ? undefined : value,
|
|
141
144
|
})
|
|
142
145
|
}
|
|
143
|
-
value={search.
|
|
146
|
+
value={search.channelId ?? "all"}
|
|
147
|
+
>
|
|
148
|
+
<SelectTrigger
|
|
149
|
+
aria-label="Channel"
|
|
150
|
+
className="h-8 w-[calc(50%-0.25rem)] min-w-[132px] text-xs sm:w-[140px]"
|
|
151
|
+
>
|
|
152
|
+
<SelectValue />
|
|
153
|
+
</SelectTrigger>
|
|
154
|
+
<SelectContent>
|
|
155
|
+
<SelectGroup>
|
|
156
|
+
<SelectItem value="all">All Channels</SelectItem>
|
|
157
|
+
{channels.map((channel) => (
|
|
158
|
+
<SelectItem key={channel.id} value={channel.id}>
|
|
159
|
+
{channel.name}
|
|
160
|
+
</SelectItem>
|
|
161
|
+
))}
|
|
162
|
+
</SelectGroup>
|
|
163
|
+
</SelectContent>
|
|
164
|
+
</Select>
|
|
165
|
+
<Select
|
|
166
|
+
disabled={!channelSelected}
|
|
167
|
+
items={platformFilterItems}
|
|
168
|
+
onValueChange={(value) =>
|
|
169
|
+
onChange({ platform: value === "android" ? "android" : "ios" })
|
|
170
|
+
}
|
|
171
|
+
value={search.platform ?? "ios"}
|
|
144
172
|
>
|
|
145
173
|
<SelectTrigger
|
|
146
174
|
aria-label="Platform"
|
|
147
175
|
className="h-8 w-[calc(50%-0.25rem)] min-w-[132px] text-xs sm:w-[140px]"
|
|
176
|
+
title={channelSelected ? undefined : "Choose a channel first"}
|
|
148
177
|
>
|
|
149
178
|
<SelectValue />
|
|
150
179
|
</SelectTrigger>
|
|
151
180
|
<SelectContent>
|
|
152
181
|
<SelectGroup>
|
|
153
|
-
<SelectItem value="all">All Platforms</SelectItem>
|
|
154
182
|
<SelectItem value="ios">iOS</SelectItem>
|
|
155
183
|
<SelectItem value="android">Android</SelectItem>
|
|
156
184
|
</SelectGroup>
|
|
157
185
|
</SelectContent>
|
|
158
186
|
</Select>
|
|
159
|
-
<Input
|
|
160
|
-
aria-label="Target app version"
|
|
161
|
-
className="h-8 w-full min-w-[132px] text-xs sm:w-[160px]"
|
|
162
|
-
onBlur={applyTargetAppVersion}
|
|
163
|
-
onChange={(event) => setTargetAppVersion(event.target.value)}
|
|
164
|
-
onKeyDown={(event) => {
|
|
165
|
-
if (event.key === "Enter") {
|
|
166
|
-
applyTargetAppVersion();
|
|
167
|
-
}
|
|
168
|
-
}}
|
|
169
|
-
placeholder="Target version"
|
|
170
|
-
value={targetAppVersion}
|
|
171
|
-
/>
|
|
172
187
|
<Select
|
|
173
|
-
|
|
188
|
+
disabled={!channelSelected && search.scopeKey === undefined}
|
|
189
|
+
items={statusFilterItems}
|
|
174
190
|
onValueChange={(value) =>
|
|
175
191
|
onChange({
|
|
176
|
-
|
|
192
|
+
enabled:
|
|
193
|
+
value === "enabled"
|
|
194
|
+
? true
|
|
195
|
+
: value === "disabled"
|
|
196
|
+
? false
|
|
197
|
+
: undefined,
|
|
177
198
|
})
|
|
178
199
|
}
|
|
179
|
-
value={
|
|
200
|
+
value={
|
|
201
|
+
search.enabled === undefined
|
|
202
|
+
? "all"
|
|
203
|
+
: search.enabled
|
|
204
|
+
? "enabled"
|
|
205
|
+
: "disabled"
|
|
206
|
+
}
|
|
180
207
|
>
|
|
181
208
|
<SelectTrigger
|
|
182
|
-
aria-label="
|
|
209
|
+
aria-label="Status"
|
|
183
210
|
className="h-8 w-[calc(50%-0.25rem)] min-w-[132px] text-xs sm:w-[140px]"
|
|
184
211
|
>
|
|
185
212
|
<SelectValue />
|
|
186
213
|
</SelectTrigger>
|
|
187
214
|
<SelectContent>
|
|
188
215
|
<SelectGroup>
|
|
189
|
-
<SelectItem value="all">
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
{channel.name}
|
|
193
|
-
</SelectItem>
|
|
194
|
-
))}
|
|
216
|
+
<SelectItem value="all">Any Status</SelectItem>
|
|
217
|
+
<SelectItem value="enabled">Enabled</SelectItem>
|
|
218
|
+
<SelectItem value="disabled">Disabled</SelectItem>
|
|
195
219
|
</SelectGroup>
|
|
196
220
|
</SelectContent>
|
|
197
221
|
</Select>
|
|
@@ -217,6 +241,19 @@ function BundleFilterToolbar({
|
|
|
217
241
|
</button>
|
|
218
242
|
</Badge>
|
|
219
243
|
) : null}
|
|
244
|
+
{search.scopeKey ? (
|
|
245
|
+
<Badge className="max-w-48 gap-1" variant="secondary">
|
|
246
|
+
Target filter
|
|
247
|
+
<button
|
|
248
|
+
aria-label="Clear target filter"
|
|
249
|
+
className="rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
250
|
+
onClick={() => onChange({ scopeKey: undefined })}
|
|
251
|
+
type="button"
|
|
252
|
+
>
|
|
253
|
+
<X className="size-3" />
|
|
254
|
+
</button>
|
|
255
|
+
</Badge>
|
|
256
|
+
) : null}
|
|
220
257
|
{hasFilters ? (
|
|
221
258
|
<Button
|
|
222
259
|
className="h-8 px-2 text-xs text-muted-foreground hover:text-foreground sm:ml-auto"
|
|
@@ -283,7 +320,7 @@ function BundleEntry({
|
|
|
283
320
|
<BundleIdDisplay bundleId={release.id} fullOnMobile />
|
|
284
321
|
{!release.bundle_id ? (
|
|
285
322
|
<span className="inline-flex items-center gap-1.5 text-sm">
|
|
286
|
-
<RotateCcw className="size-3.5" /> Built-in
|
|
323
|
+
<RotateCcw className="size-3.5" /> Built-in bundle
|
|
287
324
|
</span>
|
|
288
325
|
) : null}
|
|
289
326
|
</button>
|
|
@@ -294,9 +331,9 @@ function BundleEntry({
|
|
|
294
331
|
) : null}
|
|
295
332
|
{release.currentlyUnreachable ? (
|
|
296
333
|
<span
|
|
297
|
-
aria-label="
|
|
334
|
+
aria-label="Unreachable: no device gets this bundle with the current delivery settings."
|
|
298
335
|
className="inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground"
|
|
299
|
-
title="No
|
|
336
|
+
title="No device gets this bundle with the current delivery settings."
|
|
300
337
|
>
|
|
301
338
|
<CircleOff className="size-3.5" />
|
|
302
339
|
Unreachable
|
|
@@ -376,13 +413,8 @@ function BundlesPage() {
|
|
|
376
413
|
const releasesQuery = useReleasesQuery({
|
|
377
414
|
afterReleaseId: search.afterReleaseId,
|
|
378
415
|
beforeReleaseId: search.beforeReleaseId,
|
|
379
|
-
|
|
380
|
-
channelId: search.channelId,
|
|
381
|
-
enabled: search.enabled,
|
|
416
|
+
filter: releaseFilterOf(search),
|
|
382
417
|
limit: PAGE_SIZE,
|
|
383
|
-
page: search.page,
|
|
384
|
-
platform: search.platform,
|
|
385
|
-
targetAppVersion: search.targetAppVersion,
|
|
386
418
|
});
|
|
387
419
|
const channelsQuery = useChannelsQuery();
|
|
388
420
|
const channels = channelsQuery.data ?? [];
|
|
@@ -396,17 +428,26 @@ function BundlesPage() {
|
|
|
396
428
|
);
|
|
397
429
|
const patchCountsQuery = useBundleChildCountsQuery(bundleIds);
|
|
398
430
|
const patchCountsByBundleId = patchCountsQuery.data ?? {};
|
|
399
|
-
const
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
431
|
+
const nextCursor = releasesQuery.data?.next;
|
|
432
|
+
const previousCursor = releasesQuery.data?.previous;
|
|
433
|
+
const slotReleases = releases.flatMap((release) => {
|
|
434
|
+
const channel = channels.find(
|
|
435
|
+
(item) => item.id === release.channel_id,
|
|
436
|
+
)?.name;
|
|
437
|
+
return channel
|
|
438
|
+
? [
|
|
439
|
+
{
|
|
440
|
+
releaseId: release.id,
|
|
441
|
+
platform: release.platform,
|
|
442
|
+
channel,
|
|
443
|
+
builtIn: !release.bundle_id,
|
|
444
|
+
},
|
|
445
|
+
]
|
|
446
|
+
: [];
|
|
447
|
+
});
|
|
448
|
+
// Features add columns, such as release activity where the console reads it.
|
|
449
|
+
const featureColumns = useReleaseColumns();
|
|
450
|
+
const columnCount = 10 + featureColumns.length;
|
|
410
451
|
const channelNames = new Map(
|
|
411
452
|
channels.map((channel) => [channel.id, channel.name]),
|
|
412
453
|
);
|
|
@@ -435,33 +476,31 @@ function BundlesPage() {
|
|
|
435
476
|
}
|
|
436
477
|
changeFilters({ bundleId: bundle.id });
|
|
437
478
|
};
|
|
438
|
-
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
: null;
|
|
479
|
+
// Pages go by key: newer or older than an edge release, never by number.
|
|
480
|
+
const onLaterPage =
|
|
481
|
+
search.afterReleaseId !== undefined || search.beforeReleaseId !== undefined;
|
|
482
|
+
const previousSearch: ReleaseSearch | null = previousCursor
|
|
483
|
+
? {
|
|
484
|
+
...search,
|
|
485
|
+
afterReleaseId: previousCursor,
|
|
486
|
+
beforeReleaseId: undefined,
|
|
487
|
+
releaseId: undefined,
|
|
488
|
+
}
|
|
489
|
+
: null;
|
|
490
|
+
const nextSearch: ReleaseSearch | null = nextCursor
|
|
491
|
+
? {
|
|
492
|
+
...search,
|
|
493
|
+
afterReleaseId: undefined,
|
|
494
|
+
beforeReleaseId: nextCursor,
|
|
495
|
+
releaseId: undefined,
|
|
496
|
+
}
|
|
497
|
+
: null;
|
|
498
|
+
const newestSearch: ReleaseSearch = {
|
|
499
|
+
...search,
|
|
500
|
+
afterReleaseId: undefined,
|
|
501
|
+
beforeReleaseId: undefined,
|
|
502
|
+
releaseId: undefined,
|
|
503
|
+
};
|
|
465
504
|
|
|
466
505
|
return (
|
|
467
506
|
<div className="flex h-svh min-h-0 min-w-0 flex-col">
|
|
@@ -503,13 +542,24 @@ function BundlesPage() {
|
|
|
503
542
|
|
|
504
543
|
return (
|
|
505
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. */}
|
|
506
547
|
<article
|
|
548
|
+
aria-label={`Bundle ${release.id}`}
|
|
507
549
|
className={cn(
|
|
508
|
-
"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",
|
|
509
551
|
release.currentlyUnreachable &&
|
|
510
|
-
"bg-muted/35 saturate-50
|
|
552
|
+
"bg-muted/35 saturate-50 hover:bg-muted/50 hover:saturate-100 focus-within:saturate-100",
|
|
511
553
|
isExpanded && "border-b-0 bg-primary/5",
|
|
512
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
|
+
)}
|
|
513
563
|
>
|
|
514
564
|
<div className="flex items-start justify-between gap-3">
|
|
515
565
|
<BundleEntry
|
|
@@ -568,24 +618,29 @@ function BundlesPage() {
|
|
|
568
618
|
: "—"}
|
|
569
619
|
</dd>
|
|
570
620
|
</div>
|
|
571
|
-
|
|
572
|
-
<
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
<
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
621
|
+
{featureColumns.map(({ Cell, feature, label }) => (
|
|
622
|
+
<div
|
|
623
|
+
className="col-span-2 rounded-md bg-muted/40 p-3"
|
|
624
|
+
key={feature}
|
|
625
|
+
>
|
|
626
|
+
<dt className="mb-2 text-muted-foreground">
|
|
627
|
+
{label}
|
|
628
|
+
</dt>
|
|
629
|
+
<dd>
|
|
630
|
+
<Cell
|
|
631
|
+
releaseId={release.id}
|
|
632
|
+
releases={slotReleases}
|
|
633
|
+
/>
|
|
634
|
+
</dd>
|
|
635
|
+
</div>
|
|
636
|
+
))}
|
|
582
637
|
<div className="col-span-2 flex flex-wrap items-center gap-2 rounded-md bg-muted/40 p-3">
|
|
583
638
|
<ReleaseStateBadge release={release} />
|
|
584
639
|
{release.should_force_update ? (
|
|
585
640
|
<Badge variant="secondary">Force update</Badge>
|
|
586
641
|
) : null}
|
|
587
642
|
</div>
|
|
588
|
-
<div className="col-span-2 grid gap-2 rounded-md border bg-background/80 p-3">
|
|
643
|
+
<div className="col-span-2 grid grid-cols-1 gap-2 rounded-md border bg-background/80 p-3">
|
|
589
644
|
<div className="flex items-start justify-between gap-3">
|
|
590
645
|
<dt className="text-muted-foreground">
|
|
591
646
|
Target
|
|
@@ -619,13 +674,11 @@ function BundlesPage() {
|
|
|
619
674
|
})
|
|
620
675
|
) : (
|
|
621
676
|
<p className="p-8 text-center text-sm text-muted-foreground">
|
|
622
|
-
{
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
? "No bundles match these filters."
|
|
628
|
-
: "No bundles yet. Deploy an update to see it here."}
|
|
677
|
+
{onLaterPage
|
|
678
|
+
? "No more bundles on this side."
|
|
679
|
+
: hasReleaseFilters(search)
|
|
680
|
+
? "No bundles match these filters."
|
|
681
|
+
: "No bundles yet. Deploy an update to see it here."}
|
|
629
682
|
</p>
|
|
630
683
|
)}
|
|
631
684
|
</div>
|
|
@@ -641,7 +694,9 @@ function BundlesPage() {
|
|
|
641
694
|
<TableHead>Enabled</TableHead>
|
|
642
695
|
<TableHead>Force update</TableHead>
|
|
643
696
|
<TableHead>Rollout</TableHead>
|
|
644
|
-
|
|
697
|
+
{featureColumns.map(({ feature, label }) => (
|
|
698
|
+
<TableHead key={feature}>{label}</TableHead>
|
|
699
|
+
))}
|
|
645
700
|
<TableHead>Message</TableHead>
|
|
646
701
|
<TableHead>Created</TableHead>
|
|
647
702
|
</TableRow>
|
|
@@ -650,7 +705,7 @@ function BundlesPage() {
|
|
|
650
705
|
{releasesQuery.isPending
|
|
651
706
|
? Array.from({ length: 7 }, (_, index) => (
|
|
652
707
|
<TableRow key={index}>
|
|
653
|
-
<TableCell colSpan={
|
|
708
|
+
<TableCell colSpan={columnCount}>
|
|
654
709
|
<Skeleton className="h-8 w-full" />
|
|
655
710
|
</TableCell>
|
|
656
711
|
</TableRow>
|
|
@@ -674,17 +729,9 @@ function BundlesPage() {
|
|
|
674
729
|
? "selected"
|
|
675
730
|
: undefined
|
|
676
731
|
}
|
|
677
|
-
onClick={(
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
event.target.closest(
|
|
681
|
-
"button, a, input, select, textarea",
|
|
682
|
-
)
|
|
683
|
-
) {
|
|
684
|
-
return;
|
|
685
|
-
}
|
|
686
|
-
go({ ...search, releaseId: release.id }, false);
|
|
687
|
-
}}
|
|
732
|
+
onClick={openOutsideControls(() =>
|
|
733
|
+
go({ ...search, releaseId: release.id }, false),
|
|
734
|
+
)}
|
|
688
735
|
onKeyDown={(event) => {
|
|
689
736
|
if (
|
|
690
737
|
event.target !== event.currentTarget ||
|
|
@@ -807,12 +854,14 @@ function BundlesPage() {
|
|
|
807
854
|
percentage={release.rollout_cohort_count / 10}
|
|
808
855
|
/>
|
|
809
856
|
</TableCell>
|
|
810
|
-
|
|
811
|
-
<
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
857
|
+
{featureColumns.map(({ Cell, feature }) => (
|
|
858
|
+
<TableCell key={feature}>
|
|
859
|
+
<Cell
|
|
860
|
+
releaseId={release.id}
|
|
861
|
+
releases={slotReleases}
|
|
862
|
+
/>
|
|
863
|
+
</TableCell>
|
|
864
|
+
))}
|
|
816
865
|
<TableCell
|
|
817
866
|
className="text-sm text-muted-foreground"
|
|
818
867
|
title={release.message ?? undefined}
|
|
@@ -834,7 +883,7 @@ function BundlesPage() {
|
|
|
834
883
|
<TableRow className="hover:bg-transparent">
|
|
835
884
|
<TableCell
|
|
836
885
|
className="border-t-0 p-0"
|
|
837
|
-
colSpan={
|
|
886
|
+
colSpan={columnCount}
|
|
838
887
|
>
|
|
839
888
|
<ReleaseBundleChildrenPanel
|
|
840
889
|
onDetailClick={openChildBundle}
|
|
@@ -851,15 +900,13 @@ function BundlesPage() {
|
|
|
851
900
|
<TableRow>
|
|
852
901
|
<TableCell
|
|
853
902
|
className="h-40 text-center text-muted-foreground"
|
|
854
|
-
colSpan={
|
|
903
|
+
colSpan={columnCount}
|
|
855
904
|
>
|
|
856
|
-
{
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
? "No bundles match these filters."
|
|
862
|
-
: "No bundles yet. Deploy an update to see it here."}
|
|
905
|
+
{onLaterPage
|
|
906
|
+
? "No more bundles on this side."
|
|
907
|
+
: hasReleaseFilters(search)
|
|
908
|
+
? "No bundles match these filters."
|
|
909
|
+
: "No bundles yet. Deploy an update to see it here."}
|
|
863
910
|
</TableCell>
|
|
864
911
|
</TableRow>
|
|
865
912
|
) : null}
|
|
@@ -875,13 +922,23 @@ function BundlesPage() {
|
|
|
875
922
|
className="flex flex-col gap-3 px-2 sm:flex-row sm:items-center sm:justify-between"
|
|
876
923
|
>
|
|
877
924
|
<p className="text-xs font-medium text-muted-foreground">
|
|
878
|
-
|
|
879
|
-
|
|
925
|
+
<span className="text-foreground">{releases.length}</span>{" "}
|
|
926
|
+
{releases.length === 1 ? "entry" : "entries"}, newest first
|
|
880
927
|
</p>
|
|
881
928
|
<div className="flex flex-wrap items-center gap-3 sm:justify-end">
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
929
|
+
{onLaterPage ? (
|
|
930
|
+
<Link
|
|
931
|
+
className={buttonVariants({
|
|
932
|
+
className: "h-8 flex-1 px-3 text-xs sm:flex-none",
|
|
933
|
+
size: "sm",
|
|
934
|
+
variant: "ghost",
|
|
935
|
+
})}
|
|
936
|
+
search={newestSearch}
|
|
937
|
+
to="/"
|
|
938
|
+
>
|
|
939
|
+
Newest
|
|
940
|
+
</Link>
|
|
941
|
+
) : null}
|
|
885
942
|
{previousSearch ? (
|
|
886
943
|
<Link
|
|
887
944
|
className={buttonVariants({
|
|
@@ -940,6 +997,7 @@ function BundlesPage() {
|
|
|
940
997
|
onOpenChange={(open) =>
|
|
941
998
|
!open && go({ ...search, releaseId: undefined }, false)
|
|
942
999
|
}
|
|
1000
|
+
onShowScope={(scopeKey) => changeFilters({ scopeKey })}
|
|
943
1001
|
open={Boolean(search.releaseId)}
|
|
944
1002
|
releaseId={search.releaseId ?? ""}
|
|
945
1003
|
/>
|