+
{text.gray}
+
+
+
+
+ {day && (day.limited || day.status === 'partial') && (
+
+ )}
+ {day?.status === 'expired' || day?.status === 'unavailable' ? (
+
+ ) : (
+
+ )}
+
{text.hermes}
+
+
(
+
+ ),
+ }}
+ />
+ {text.offers}
+ {text.offersNote}
+
+
+ )}
+
+
+ );
+};
diff --git a/src/pages/app-insights/release-insights-types.ts b/src/pages/app-insights/release-insights-types.ts
new file mode 100644
index 0000000..d327b37
--- /dev/null
+++ b/src/pages/app-insights/release-insights-types.ts
@@ -0,0 +1,80 @@
+export interface ReleaseCounts {
+ exposed: number;
+ hit: number;
+ miss: number;
+ unknown: number;
+ missingUUID: number;
+ missingSDK: number;
+ missingRule: number;
+}
+
+export interface RolloutInsight {
+ id: string;
+ packageVersion: string;
+ mainHash: string;
+ targetHash: string;
+ rollout: number | null;
+ algorithm: string;
+ ruleDigest: string;
+ requests: ReleaseCounts;
+ exposedDevices: number | null;
+ hitDevices: number | null;
+ missDevices: number | null;
+ unknownDevices: number | null;
+ hitRate: number | null;
+ status: string;
+ inferred: boolean;
+ approximate: boolean;
+}
+
+export interface ReleaseDelivery {
+ id: string;
+ hash: string;
+ target: string;
+ kind: string;
+ reason: string;
+ count: number;
+}
+
+export interface ReleaseInsightDay {
+ date: string;
+ status: string;
+ requests: number | null;
+ limited: boolean;
+ cohorts: RolloutInsight[];
+ deliveries: ReleaseDelivery[];
+}
+
+export interface ArtifactInsight {
+ key: string;
+ fromHash: string;
+ toHash: string;
+ taskType: string;
+ state: string;
+ format: string;
+ observedAt: string;
+ artifactBytes: number | null;
+ fullBytes: number | null;
+ reduction: number | null;
+}
+
+export interface ReleaseVersionInsight {
+ hash: string;
+ name: string;
+ bytecodeVersion: number | null;
+ baseVersionId: number | null;
+ hermesBaseOutcome: string;
+ hermesBaseDetail: string;
+ artifactStatus: string;
+ artifactsLimited: boolean;
+ artifacts: ArtifactInsight[];
+}
+
+export interface ReleaseInsights {
+ status: string;
+ timezone: string;
+ retentionDays: number;
+ artifactRetentionDays: number;
+ days: ReleaseInsightDay[];
+ versions: ReleaseVersionInsight[];
+}
diff --git a/src/pages/app-insights/types.ts b/src/pages/app-insights/types.ts
index 36e24bc..30a5f0e 100644
--- a/src/pages/app-insights/types.ts
+++ b/src/pages/app-insights/types.ts
@@ -134,6 +134,7 @@ export interface VersionFunnel {
}
export interface VersionFunnelResponse {
+ releaseInsights?: import('./release-insights-types').ReleaseInsights;
days: number;
start: string;
end: string;
diff --git a/src/pages/realtime-metrics.tsx b/src/pages/realtime-metrics.tsx
index 571a224..5fdd282 100644
--- a/src/pages/realtime-metrics.tsx
+++ b/src/pages/realtime-metrics.tsx
@@ -19,6 +19,7 @@ import {
} from './app-insights/logic';
import { OverviewPanel } from './app-insights/overview-panel';
import { hasRealtimeSeriesEntryParams } from './app-insights/realtime-series-panel';
+import { ReleaseInsightsPanel } from './app-insights/release-insights-panel';
import { TrafficPanel } from './app-insights/traffic-panel';
import { VersionsPanel } from './app-insights/versions-panel';
@@ -149,7 +150,10 @@ export const Component = () => {
onNavigate={setView}
/>
) : view === 'versions' ? (
-
+ <>
+
+
+ >
) : view === 'traffic' ? (
) : (