@c2l2c/backstage-plugin-dora-metrics 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/alpha.d.ts CHANGED
@@ -1,60 +1,5 @@
1
- import * as _backstage_catalog_model from '@backstage/catalog-model';
2
- import * as react from 'react';
3
- import * as _backstage_filter_predicates from '@backstage/filter-predicates';
4
1
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
5
2
 
6
- declare const doraMetricsPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{}, {}, {
7
- "api:dora-metrics/dora-metrics": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
8
- kind: "api";
9
- name: "dora-metrics";
10
- config: {};
11
- configInput: {};
12
- output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
13
- inputs: {};
14
- params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
15
- }>;
16
- "entity-content:dora-metrics": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
17
- kind: "entity-content";
18
- name: undefined;
19
- config: {
20
- path: string | undefined;
21
- title: string | undefined;
22
- filter: _backstage_filter_predicates.FilterPredicate | undefined;
23
- group: string | false | undefined;
24
- icon: string | undefined;
25
- };
26
- configInput: {
27
- filter?: _backstage_filter_predicates.FilterPredicate | undefined;
28
- title?: string | undefined;
29
- path?: string | undefined;
30
- group?: string | false | undefined;
31
- icon?: string | undefined;
32
- };
33
- output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
34
- optional: true;
35
- }> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
36
- optional: true;
37
- }> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-filter-expression", {
38
- optional: true;
39
- }> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-content-group", {
40
- optional: true;
41
- }> | _backstage_frontend_plugin_api.ExtensionDataRef<string | react.ReactElement<any, string | react.JSXElementConstructor<any>>, "catalog.entity-content-icon", {
42
- optional: true;
43
- }>;
44
- inputs: {};
45
- params: {
46
- defaultPath?: [Error: `Use the 'path' param instead`];
47
- path: string;
48
- defaultTitle?: [Error: `Use the 'title' param instead`];
49
- title: string;
50
- defaultGroup?: [Error: `Use the 'group' param instead`];
51
- group?: ("overview" | "documentation" | "development" | "deployment" | "operation" | "observability") | (string & {});
52
- icon?: string | react.ReactElement;
53
- loader: () => Promise<JSX.Element>;
54
- routeRef?: _backstage_frontend_plugin_api.RouteRef;
55
- filter?: string | _backstage_filter_predicates.FilterPredicate | ((entity: _backstage_catalog_model.Entity) => boolean);
56
- };
57
- }>;
58
- }>;
3
+ declare const doraMetricsPlugin: _backstage_frontend_plugin_api.FrontendPlugin<{}, {}, {}>;
59
4
 
60
5
  export { doraMetricsPlugin as default };
@@ -34,11 +34,11 @@ function matchesLabel(prLabels, labelPattern) {
34
34
  if (!labelPattern) return false;
35
35
  const names = prLabels.map((l) => l.name);
36
36
  if (isRegexPattern(labelPattern)) {
37
- const regex = new RegExp(labelPattern);
37
+ const regex = new RegExp(labelPattern, "i");
38
38
  return names.some((n) => regex.test(n));
39
39
  }
40
- const patterns = labelPattern.split(",").map((l) => l.trim()).filter(Boolean);
41
- return names.some((n) => patterns.includes(n));
40
+ const patterns = labelPattern.split(",").map((l) => l.trim().toLowerCase()).filter(Boolean);
41
+ return names.some((n) => patterns.includes(n.toLowerCase()));
42
42
  }
43
43
  async function resolveBranches(owner, repo, branchPattern, fetchFn) {
44
44
  if (isRegexPattern(branchPattern)) {
@@ -116,14 +116,19 @@ class DoraMetricsClient {
116
116
  const allByNumber = /* @__PURE__ */ new Map();
117
117
  await Promise.all(
118
118
  branches.map(async (branch) => {
119
- const url = `https://api.github.com/repos/${owner}/${repo}/pulls?state=closed&base=${branch}&per_page=100`;
120
- const prs = await boundFetch(url);
121
- for (const pr of prs) {
122
- if (pr.merged_at && new Date(pr.merged_at) >= cutoff) {
123
- if (!allByNumber.has(pr.number)) {
124
- allByNumber.set(pr.number, pr);
119
+ let hasMore = true;
120
+ for (let page = 1; hasMore; page++) {
121
+ const url = `https://api.github.com/repos/${owner}/${repo}/pulls?state=closed&base=${encodeURIComponent(branch)}&per_page=100&page=${page}&sort=updated&direction=desc`;
122
+ const prs = await boundFetch(url);
123
+ for (const pr of prs) {
124
+ if (pr.merged_at && new Date(pr.merged_at) >= cutoff) {
125
+ if (!allByNumber.has(pr.number)) {
126
+ allByNumber.set(pr.number, pr);
127
+ }
125
128
  }
126
129
  }
130
+ const oldestUpdatedMs = prs.length > 0 ? Math.min(...prs.map((pr) => new Date(pr.updated_at).getTime())) : 0;
131
+ hasMore = prs.length >= 100 && oldestUpdatedMs >= cutoff.getTime();
127
132
  }
128
133
  })
129
134
  );
@@ -236,8 +241,9 @@ class DoraMetricsClient {
236
241
  );
237
242
  mttrHours = hotfixDurations.length > 0 ? Math.round(hotfixDurations.reduce((a, b) => a + b, 0) / hotfixDurations.length * 10) / 10 : 0;
238
243
  }
244
+ const labelDate = new Date(Math.min(weekEnd.getTime(), Date.now()));
239
245
  buckets.push({
240
- weekLabel: weekStart.toLocaleDateString("en-US", { month: "short", day: "numeric" }),
246
+ weekLabel: labelDate.toLocaleDateString("en-US", { month: "short", day: "numeric" }),
241
247
  bucketMidMs: Math.round((weekStart.getTime() + weekEnd.getTime()) / 2),
242
248
  deploymentCount: weekPRs.length,
243
249
  leadTimeHours: Math.round(avgLeadTime * 10) / 10,
@@ -1 +1 @@
1
- {"version":3,"file":"DoraMetricsClient.esm.js","sources":["../../src/api/DoraMetricsClient.ts"],"sourcesContent":["import { ConfigApi, OAuthApi } from '@backstage/core-plugin-api';\nimport {\n DoraEnvironment,\n DoraHistoryPoint,\n DoraMetrics,\n DoraMetricValue,\n DoraMetricsApi,\n DoraRating,\n DoraTargets,\n PrDetail,\n} from './types';\n\ninterface GitHubPR {\n number: number;\n title: string;\n html_url: string;\n created_at: string;\n merged_at: string | null;\n closed_at: string | null;\n labels: Array<{ name: string }>;\n user: { login: string; avatar_url: string } | null;\n}\n\n/**\n * Compute a DORA rating based on the configured target.\n *\n * lowerIsBetter (lead time, CFR, MTTR, hotfix count):\n * elite = value <= target\n * high = value <= target * 2\n * medium = value <= target * 4\n * low = value > target * 4\n *\n * higherIsBetter (deployment frequency):\n * elite = value >= target\n * high = value >= target * 0.7\n * medium = value >= target * 0.4\n * low = value < target * 0.4\n *\n * Special case — target = 0 (hotfix count ideal = 0):\n * elite=0, high≤2, medium≤5, low>5\n */\nfunction computeRating(value: number, target: number, lowerIsBetter: boolean): DoraRating {\n if (lowerIsBetter) {\n if (target === 0) {\n if (value === 0) return 'elite';\n if (value <= 2) return 'high';\n if (value <= 5) return 'medium';\n return 'low';\n }\n if (value <= target) return 'elite';\n if (value <= target * 2) return 'high';\n if (value <= target * 4) return 'medium';\n return 'low';\n }\n if (value >= target) return 'elite';\n if (value >= target * 0.7) return 'high';\n if (value >= target * 0.4) return 'medium';\n return 'low';\n}\n\nfunction toPrDetail(pr: GitHubPR, durationHours: number): PrDetail {\n return {\n number: pr.number,\n title: pr.title,\n url: pr.html_url,\n durationHours: Math.round(durationHours * 10) / 10,\n mergedAt: pr.merged_at!,\n author: pr.user?.login,\n authorAvatar: pr.user?.avatar_url,\n };\n}\n\n/**\n * Determine whether a pattern string is a regex (vs a plain name or\n * comma-separated list of names). A string is treated as a regex if it\n * contains any regex meta-character: | ^ $ [ ] ( ) { } ? + * \\\n */\nfunction isRegexPattern(pattern: string): boolean {\n return /[|^$[\\](){}?+*\\\\]/.test(pattern);\n}\n\n/**\n * Return true if any of the PR's labels match the label pattern.\n *\n * Supports the same three formats as branch patterns:\n * - Single name: \"hotfix\"\n * - Comma-separated: \"hotfix,fix,bug\"\n * - JavaScript regex: \"^(hotfix|fix)$\"\n */\nfunction matchesLabel(prLabels: Array<{ name: string }>, labelPattern: string): boolean {\n if (!labelPattern) return false;\n const names = prLabels.map(l => l.name);\n if (isRegexPattern(labelPattern)) {\n const regex = new RegExp(labelPattern);\n return names.some(n => regex.test(n));\n }\n const patterns = labelPattern.split(',').map(l => l.trim()).filter(Boolean);\n return names.some(n => patterns.includes(n));\n}\n\n/**\n * Resolve a branch pattern to a concrete list of branch names.\n *\n * - Single name \"main\" → [\"main\"]\n * - Comma-sep \"main,master\" → [\"main\", \"master\"]\n * - Regex \"^(main|master)$\"→ fetched from the repo's branch list and filtered\n */\nasync function resolveBranches(\n owner: string,\n repo: string,\n branchPattern: string,\n fetchFn: <T>(url: string) => Promise<T>,\n): Promise<string[]> {\n if (isRegexPattern(branchPattern)) {\n const repoBranches = await fetchFn<Array<{ name: string }>>(\n `https://api.github.com/repos/${owner}/${repo}/branches?per_page=100`,\n );\n const regex = new RegExp(branchPattern);\n return repoBranches.map(b => b.name).filter(name => regex.test(name));\n }\n // Comma-separated or single branch name\n return branchPattern.split(',').map(b => b.trim()).filter(Boolean);\n}\n\nexport class DoraMetricsClient implements DoraMetricsApi {\n private readonly githubAuthApi: OAuthApi;\n private readonly configApi: ConfigApi;\n\n constructor(githubAuthApi: OAuthApi, configApi: ConfigApi) {\n this.githubAuthApi = githubAuthApi;\n this.configApi = configApi;\n }\n\n private getConfig() {\n const appCfg = this.configApi.getConfig('app');\n const cfg = appCfg.getOptionalConfig('doraMetrics');\n\n const rawEnvs = cfg?.getOptionalConfigArray('environments') ?? [];\n const environments: DoraEnvironment[] = rawEnvs.map(e => ({\n name: e.getString('name'),\n branch: e.getString('branch'),\n isProduction: e.getOptionalBoolean('isProduction') ?? false,\n label: e.getOptionalString('label') ?? 'hotfix',\n }));\n\n // Validate: at most one isProduction environment\n const prodEnvs = environments.filter(e => e.isProduction);\n if (prodEnvs.length > 1) {\n throw new Error(\n `DORA metrics config error: only one environment may have isProduction: true, ` +\n `but found ${prodEnvs.length}: ${prodEnvs.map(e => e.name).join(', ')}`,\n );\n }\n\n const initialDays =\n cfg?.getOptionalConfig('collection')?.getOptionalNumber('initialDays') ?? 30;\n\n const targetsCfg = cfg?.getOptionalConfig('targets');\n const targets: DoraTargets = {\n deploymentFrequency: targetsCfg?.getOptionalNumber('deploymentFrequency') ?? 7,\n leadTime: targetsCfg?.getOptionalNumber('leadTime') ?? 24,\n changeFailureRate: targetsCfg?.getOptionalNumber('changeFailureRate') ?? 15,\n mttr: targetsCfg?.getOptionalNumber('mttr') ?? 1,\n };\n\n return { environments, initialDays, targets };\n }\n\n getEnvironments(): DoraEnvironment[] {\n return this.getConfig().environments;\n }\n\n getDefaultDays(): number {\n return this.getConfig().initialDays;\n }\n\n getTargets(): DoraTargets {\n return this.getConfig().targets;\n }\n\n private async fetchWithAuth<T>(url: string, token: string): Promise<T> {\n const response = await fetch(url, {\n headers: {\n Authorization: `token ${token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub API request failed: ${response.status} ${response.statusText} — ${url}`,\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Fetch all merged PRs for an environment, resolving branch patterns and\n * deduplicating across multiple branches by PR number.\n */\n private async fetchMergedPRs(\n owner: string,\n repo: string,\n env: DoraEnvironment,\n cutoff: Date,\n token: string,\n ): Promise<GitHubPR[]> {\n const boundFetch = <T>(url: string) => this.fetchWithAuth<T>(url, token);\n\n const branches = await resolveBranches(owner, repo, env.branch, boundFetch);\n\n const allByNumber = new Map<number, GitHubPR>();\n\n await Promise.all(\n branches.map(async branch => {\n const url =\n `https://api.github.com/repos/${owner}/${repo}/pulls` +\n `?state=closed&base=${branch}&per_page=100`;\n const prs = await boundFetch<GitHubPR[]>(url);\n for (const pr of prs) {\n if (pr.merged_at && new Date(pr.merged_at) >= cutoff) {\n // Keep first occurrence (branches may share PRs — shouldn't happen\n // for base-branch-filtered queries, but guard anyway)\n if (!allByNumber.has(pr.number)) {\n allByNumber.set(pr.number, pr);\n }\n }\n }\n }),\n );\n\n return Array.from(allByNumber.values());\n }\n\n async getMetrics(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n targetsOverride?: Partial<DoraTargets>,\n ): Promise<DoraMetrics> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const { targets: configTargets } = this.getConfig();\n const targets: DoraTargets = { ...configTargets, ...targetsOverride };\n\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) {\n throw new Error(`Invalid project slug \"${projectSlug}\". Expected \"owner/repo\".`);\n }\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // --- Deployment Frequency ---\n const deploymentsPerWeek = days > 0 ? (mergedPRs.length / days) * 7 : 0;\n\n const deploymentFrequency: DoraMetricValue = {\n value: Math.round(deploymentsPerWeek * 100) / 100,\n unit: 'per week',\n rating: computeRating(deploymentsPerWeek, targets.deploymentFrequency, false),\n target: targets.deploymentFrequency,\n // All merged PRs sorted newest-first — used in expanded view date table\n slowestPRs: [...mergedPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // --- Lead Time ---\n const prsWithLeadTime = mergedPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgLeadTimeHours =\n prsWithLeadTime.length > 0\n ? prsWithLeadTime.reduce((sum, p) => sum + p.durationHours, 0) / prsWithLeadTime.length\n : 0;\n\n const leadTime: DoraMetricValue = {\n value: Math.round(avgLeadTimeHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgLeadTimeHours, targets.leadTime, true),\n target: targets.leadTime,\n slowestPRs: prsWithLeadTime\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n // --- Production-only metrics ---\n if (!env.isProduction) {\n return {\n deploymentFrequency,\n leadTime,\n changeFailureRate: null,\n mttr: null,\n numberOfHotfixes: null,\n };\n }\n\n const hotfixPRs = mergedPRs.filter(pr =>\n matchesLabel(pr.labels ?? [], env.label),\n );\n\n // Number of Hotfixes — sorted newest-first for the expanded list\n const numberOfHotfixes: DoraMetricValue = {\n value: hotfixPRs.length,\n unit: 'PRs',\n rating: computeRating(hotfixPRs.length, 0, true),\n target: 0,\n slowestPRs: [...hotfixPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // Change Failure Rate = fix PRs / all merged PRs (DORA standard: always 0–100%)\n const changeFailureRatePct =\n mergedPRs.length > 0 ? (hotfixPRs.length / mergedPRs.length) * 100 : 0;\n\n const changeFailureRate: DoraMetricValue = {\n value: Math.round(changeFailureRatePct * 10) / 10,\n unit: '%',\n rating: computeRating(changeFailureRatePct, targets.changeFailureRate, true),\n target: targets.changeFailureRate,\n };\n\n // MTTR\n const hotfixWithDuration = hotfixPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgMttrHours =\n hotfixWithDuration.length > 0\n ? hotfixWithDuration.reduce((sum, p) => sum + p.durationHours, 0) /\n hotfixWithDuration.length\n : 0;\n\n const mttr: DoraMetricValue = {\n value: Math.round(avgMttrHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgMttrHours, targets.mttr, true),\n target: targets.mttr,\n slowestPRs: hotfixWithDuration\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n return { deploymentFrequency, leadTime, changeFailureRate, mttr, numberOfHotfixes };\n }\n\n async getHistory(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n ): Promise<DoraHistoryPoint[]> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) throw new Error(`Invalid project slug \"${projectSlug}\".`);\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // Scale bucket size so we always get ~7 data points regardless of date range\n const bucketDays = Math.max(1, Math.round(days / 7));\n const numBuckets = Math.max(2, Math.ceil(days / bucketDays));\n const buckets: DoraHistoryPoint[] = [];\n\n for (let w = numBuckets - 1; w >= 0; w--) {\n const weekEnd = new Date(Date.now() - w * bucketDays * 24 * 60 * 60 * 1000);\n const weekStart = new Date(weekEnd.getTime() - bucketDays * 24 * 60 * 60 * 1000);\n\n const weekPRs = mergedPRs.filter(pr => {\n const t = new Date(pr.merged_at!).getTime();\n return t >= weekStart.getTime() && t < weekEnd.getTime();\n });\n\n const leadTimes = weekPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n const avgLeadTime =\n leadTimes.length > 0 ? leadTimes.reduce((a, b) => a + b, 0) / leadTimes.length : 0;\n\n let changeFailureRate: number | undefined;\n let mttrHours: number | undefined;\n\n if (env.isProduction) {\n const hotfixPRs = weekPRs.filter(pr => matchesLabel(pr.labels, env.label));\n changeFailureRate =\n weekPRs.length > 0 ? Math.round((hotfixPRs.length / weekPRs.length) * 1000) / 10 : 0;\n const hotfixDurations = hotfixPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n mttrHours =\n hotfixDurations.length > 0\n ? Math.round((hotfixDurations.reduce((a, b) => a + b, 0) / hotfixDurations.length) * 10) / 10\n : 0;\n }\n\n buckets.push({\n weekLabel: weekStart.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),\n bucketMidMs: Math.round((weekStart.getTime() + weekEnd.getTime()) / 2),\n deploymentCount: weekPRs.length,\n leadTimeHours: Math.round(avgLeadTime * 10) / 10,\n changeFailureRate,\n mttrHours,\n });\n }\n\n return buckets;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DoraMetricsClient.esm.js","sources":["../../src/api/DoraMetricsClient.ts"],"sourcesContent":["import { ConfigApi, OAuthApi } from '@backstage/core-plugin-api';\nimport {\n DoraEnvironment,\n DoraHistoryPoint,\n DoraMetrics,\n DoraMetricValue,\n DoraMetricsApi,\n DoraRating,\n DoraTargets,\n PrDetail,\n} from './types';\n\ninterface GitHubPR {\n number: number;\n title: string;\n html_url: string;\n created_at: string;\n updated_at: string;\n merged_at: string | null;\n closed_at: string | null;\n labels: Array<{ name: string }>;\n user: { login: string; avatar_url: string } | null;\n}\n\n/**\n * Compute a DORA rating based on the configured target.\n *\n * lowerIsBetter (lead time, CFR, MTTR, hotfix count):\n * elite = value <= target\n * high = value <= target * 2\n * medium = value <= target * 4\n * low = value > target * 4\n *\n * higherIsBetter (deployment frequency):\n * elite = value >= target\n * high = value >= target * 0.7\n * medium = value >= target * 0.4\n * low = value < target * 0.4\n *\n * Special case — target = 0 (hotfix count ideal = 0):\n * elite=0, high≤2, medium≤5, low>5\n */\nfunction computeRating(value: number, target: number, lowerIsBetter: boolean): DoraRating {\n if (lowerIsBetter) {\n if (target === 0) {\n if (value === 0) return 'elite';\n if (value <= 2) return 'high';\n if (value <= 5) return 'medium';\n return 'low';\n }\n if (value <= target) return 'elite';\n if (value <= target * 2) return 'high';\n if (value <= target * 4) return 'medium';\n return 'low';\n }\n if (value >= target) return 'elite';\n if (value >= target * 0.7) return 'high';\n if (value >= target * 0.4) return 'medium';\n return 'low';\n}\n\nfunction toPrDetail(pr: GitHubPR, durationHours: number): PrDetail {\n return {\n number: pr.number,\n title: pr.title,\n url: pr.html_url,\n durationHours: Math.round(durationHours * 10) / 10,\n mergedAt: pr.merged_at!,\n author: pr.user?.login,\n authorAvatar: pr.user?.avatar_url,\n };\n}\n\n/**\n * Determine whether a pattern string is a regex (vs a plain name or\n * comma-separated list of names). A string is treated as a regex if it\n * contains any regex meta-character: | ^ $ [ ] ( ) { } ? + * \\\n */\nfunction isRegexPattern(pattern: string): boolean {\n return /[|^$[\\](){}?+*\\\\]/.test(pattern);\n}\n\n/**\n * Return true if any of the PR's labels match the label pattern.\n *\n * Supports the same three formats as branch patterns:\n * - Single name: \"hotfix\"\n * - Comma-separated: \"hotfix,fix,bug\"\n * - JavaScript regex: \"^(hotfix|fix)$\"\n */\nfunction matchesLabel(prLabels: Array<{ name: string }>, labelPattern: string): boolean {\n if (!labelPattern) return false;\n const names = prLabels.map(l => l.name);\n if (isRegexPattern(labelPattern)) {\n const regex = new RegExp(labelPattern, 'i');\n return names.some(n => regex.test(n));\n }\n const patterns = labelPattern.split(',').map(l => l.trim().toLowerCase()).filter(Boolean);\n return names.some(n => patterns.includes(n.toLowerCase()));\n}\n\n/**\n * Resolve a branch pattern to a concrete list of branch names.\n *\n * - Single name \"main\" → [\"main\"]\n * - Comma-sep \"main,master\" → [\"main\", \"master\"]\n * - Regex \"^(main|master)$\"→ fetched from the repo's branch list and filtered\n */\nasync function resolveBranches(\n owner: string,\n repo: string,\n branchPattern: string,\n fetchFn: <T>(url: string) => Promise<T>,\n): Promise<string[]> {\n if (isRegexPattern(branchPattern)) {\n const repoBranches = await fetchFn<Array<{ name: string }>>(\n `https://api.github.com/repos/${owner}/${repo}/branches?per_page=100`,\n );\n const regex = new RegExp(branchPattern);\n return repoBranches.map(b => b.name).filter(name => regex.test(name));\n }\n // Comma-separated or single branch name\n return branchPattern.split(',').map(b => b.trim()).filter(Boolean);\n}\n\nexport class DoraMetricsClient implements DoraMetricsApi {\n private readonly githubAuthApi: OAuthApi;\n private readonly configApi: ConfigApi;\n\n constructor(githubAuthApi: OAuthApi, configApi: ConfigApi) {\n this.githubAuthApi = githubAuthApi;\n this.configApi = configApi;\n }\n\n private getConfig() {\n const appCfg = this.configApi.getConfig('app');\n const cfg = appCfg.getOptionalConfig('doraMetrics');\n\n const rawEnvs = cfg?.getOptionalConfigArray('environments') ?? [];\n const environments: DoraEnvironment[] = rawEnvs.map(e => ({\n name: e.getString('name'),\n branch: e.getString('branch'),\n isProduction: e.getOptionalBoolean('isProduction') ?? false,\n label: e.getOptionalString('label') ?? 'hotfix',\n }));\n\n // Validate: at most one isProduction environment\n const prodEnvs = environments.filter(e => e.isProduction);\n if (prodEnvs.length > 1) {\n throw new Error(\n `DORA metrics config error: only one environment may have isProduction: true, ` +\n `but found ${prodEnvs.length}: ${prodEnvs.map(e => e.name).join(', ')}`,\n );\n }\n\n const initialDays =\n cfg?.getOptionalConfig('collection')?.getOptionalNumber('initialDays') ?? 30;\n\n const targetsCfg = cfg?.getOptionalConfig('targets');\n const targets: DoraTargets = {\n deploymentFrequency: targetsCfg?.getOptionalNumber('deploymentFrequency') ?? 7,\n leadTime: targetsCfg?.getOptionalNumber('leadTime') ?? 24,\n changeFailureRate: targetsCfg?.getOptionalNumber('changeFailureRate') ?? 15,\n mttr: targetsCfg?.getOptionalNumber('mttr') ?? 1,\n };\n\n return { environments, initialDays, targets };\n }\n\n getEnvironments(): DoraEnvironment[] {\n return this.getConfig().environments;\n }\n\n getDefaultDays(): number {\n return this.getConfig().initialDays;\n }\n\n getTargets(): DoraTargets {\n return this.getConfig().targets;\n }\n\n private async fetchWithAuth<T>(url: string, token: string): Promise<T> {\n const response = await fetch(url, {\n headers: {\n Authorization: `token ${token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub API request failed: ${response.status} ${response.statusText} — ${url}`,\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Fetch all merged PRs for an environment, resolving branch patterns and\n * deduplicating across multiple branches by PR number.\n */\n private async fetchMergedPRs(\n owner: string,\n repo: string,\n env: DoraEnvironment,\n cutoff: Date,\n token: string,\n ): Promise<GitHubPR[]> {\n const boundFetch = <T>(url: string) => this.fetchWithAuth<T>(url, token);\n\n const branches = await resolveBranches(owner, repo, env.branch, boundFetch);\n\n const allByNumber = new Map<number, GitHubPR>();\n\n await Promise.all(\n branches.map(async branch => {\n let hasMore = true;\n for (let page = 1; hasMore; page++) {\n const url =\n `https://api.github.com/repos/${owner}/${repo}/pulls` +\n `?state=closed&base=${encodeURIComponent(branch)}&per_page=100&page=${page}&sort=updated&direction=desc`;\n const prs = await boundFetch<GitHubPR[]>(url);\n\n for (const pr of prs) {\n if (pr.merged_at && new Date(pr.merged_at) >= cutoff) {\n // Keep first occurrence — branches may share PRs\n if (!allByNumber.has(pr.number)) {\n allByNumber.set(pr.number, pr);\n }\n }\n }\n\n // PRs are sorted by updated_at desc. Since merged_at <= updated_at,\n // once the oldest updated_at on a page is before cutoff, no subsequent\n // page can contain a PR merged within the window — stop early.\n const oldestUpdatedMs = prs.length > 0\n ? Math.min(...prs.map(pr => new Date(pr.updated_at).getTime()))\n : 0;\n hasMore = prs.length >= 100 && oldestUpdatedMs >= cutoff.getTime();\n }\n }),\n );\n\n return Array.from(allByNumber.values());\n }\n\n async getMetrics(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n targetsOverride?: Partial<DoraTargets>,\n ): Promise<DoraMetrics> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const { targets: configTargets } = this.getConfig();\n const targets: DoraTargets = { ...configTargets, ...targetsOverride };\n\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) {\n throw new Error(`Invalid project slug \"${projectSlug}\". Expected \"owner/repo\".`);\n }\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // --- Deployment Frequency ---\n const deploymentsPerWeek = days > 0 ? (mergedPRs.length / days) * 7 : 0;\n\n const deploymentFrequency: DoraMetricValue = {\n value: Math.round(deploymentsPerWeek * 100) / 100,\n unit: 'per week',\n rating: computeRating(deploymentsPerWeek, targets.deploymentFrequency, false),\n target: targets.deploymentFrequency,\n // All merged PRs sorted newest-first — used in expanded view date table\n slowestPRs: [...mergedPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // --- Lead Time ---\n const prsWithLeadTime = mergedPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgLeadTimeHours =\n prsWithLeadTime.length > 0\n ? prsWithLeadTime.reduce((sum, p) => sum + p.durationHours, 0) / prsWithLeadTime.length\n : 0;\n\n const leadTime: DoraMetricValue = {\n value: Math.round(avgLeadTimeHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgLeadTimeHours, targets.leadTime, true),\n target: targets.leadTime,\n slowestPRs: prsWithLeadTime\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n // --- Production-only metrics ---\n if (!env.isProduction) {\n return {\n deploymentFrequency,\n leadTime,\n changeFailureRate: null,\n mttr: null,\n numberOfHotfixes: null,\n };\n }\n\n const hotfixPRs = mergedPRs.filter(pr =>\n matchesLabel(pr.labels ?? [], env.label),\n );\n\n // Number of Hotfixes — sorted newest-first for the expanded list\n const numberOfHotfixes: DoraMetricValue = {\n value: hotfixPRs.length,\n unit: 'PRs',\n rating: computeRating(hotfixPRs.length, 0, true),\n target: 0,\n slowestPRs: [...hotfixPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // Change Failure Rate = fix PRs / all merged PRs (DORA standard: always 0–100%)\n const changeFailureRatePct =\n mergedPRs.length > 0 ? (hotfixPRs.length / mergedPRs.length) * 100 : 0;\n\n const changeFailureRate: DoraMetricValue = {\n value: Math.round(changeFailureRatePct * 10) / 10,\n unit: '%',\n rating: computeRating(changeFailureRatePct, targets.changeFailureRate, true),\n target: targets.changeFailureRate,\n };\n\n // MTTR\n const hotfixWithDuration = hotfixPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgMttrHours =\n hotfixWithDuration.length > 0\n ? hotfixWithDuration.reduce((sum, p) => sum + p.durationHours, 0) /\n hotfixWithDuration.length\n : 0;\n\n const mttr: DoraMetricValue = {\n value: Math.round(avgMttrHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgMttrHours, targets.mttr, true),\n target: targets.mttr,\n slowestPRs: hotfixWithDuration\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n return { deploymentFrequency, leadTime, changeFailureRate, mttr, numberOfHotfixes };\n }\n\n async getHistory(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n ): Promise<DoraHistoryPoint[]> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) throw new Error(`Invalid project slug \"${projectSlug}\".`);\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // Scale bucket size so we always get ~7 data points regardless of date range\n const bucketDays = Math.max(1, Math.round(days / 7));\n const numBuckets = Math.max(2, Math.ceil(days / bucketDays));\n const buckets: DoraHistoryPoint[] = [];\n\n for (let w = numBuckets - 1; w >= 0; w--) {\n const weekEnd = new Date(Date.now() - w * bucketDays * 24 * 60 * 60 * 1000);\n const weekStart = new Date(weekEnd.getTime() - bucketDays * 24 * 60 * 60 * 1000);\n\n const weekPRs = mergedPRs.filter(pr => {\n const t = new Date(pr.merged_at!).getTime();\n return t >= weekStart.getTime() && t < weekEnd.getTime();\n });\n\n const leadTimes = weekPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n const avgLeadTime =\n leadTimes.length > 0 ? leadTimes.reduce((a, b) => a + b, 0) / leadTimes.length : 0;\n\n let changeFailureRate: number | undefined;\n let mttrHours: number | undefined;\n\n if (env.isProduction) {\n const hotfixPRs = weekPRs.filter(pr => matchesLabel(pr.labels, env.label));\n changeFailureRate =\n weekPRs.length > 0 ? Math.round((hotfixPRs.length / weekPRs.length) * 1000) / 10 : 0;\n const hotfixDurations = hotfixPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n mttrHours =\n hotfixDurations.length > 0\n ? Math.round((hotfixDurations.reduce((a, b) => a + b, 0) / hotfixDurations.length) * 10) / 10\n : 0;\n }\n\n // Label with bucket end (capped at now) so all views show \"today\" as the last label.\n const labelDate = new Date(Math.min(weekEnd.getTime(), Date.now()));\n buckets.push({\n weekLabel: labelDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),\n bucketMidMs: Math.round((weekStart.getTime() + weekEnd.getTime()) / 2),\n deploymentCount: weekPRs.length,\n leadTimeHours: Math.round(avgLeadTime * 10) / 10,\n changeFailureRate,\n mttrHours,\n });\n }\n\n return buckets;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ function niceHourTicks(maxHours) {
2
+ if (maxHours <= 0) return [0, 4, 8, 12, 16];
3
+ const steps = [0.25, 0.5, 1, 2, 4, 6, 8, 12, 24, 48, 72, 96, 168];
4
+ const step = steps.find((s) => Math.ceil(maxHours / s) <= 6) ?? 168;
5
+ const top = Math.ceil(maxHours / step) * step;
6
+ const ticks = [];
7
+ for (let v = 0; v <= top + 1e-3; v += step) ticks.push(v);
8
+ return ticks;
9
+ }
10
+ function niceCountTicks(maxCount) {
11
+ if (maxCount <= 0) return [0, 1, 2, 3, 4, 5];
12
+ const step = Math.max(1, Math.ceil(maxCount / 5));
13
+ const top = Math.ceil(maxCount / step) * step;
14
+ const ticks = [];
15
+ for (let v = 0; v <= top + 1e-3; v += step) ticks.push(v);
16
+ return ticks;
17
+ }
18
+
19
+ export { niceCountTicks, niceHourTicks };
20
+ //# sourceMappingURL=chartUtils.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chartUtils.esm.js","sources":["../../src/api/chartUtils.ts"],"sourcesContent":["/**\n * Generate clean hour-interval Y-axis ticks for time-based DORA charts.\n * Picks the smallest interval from a fixed set that keeps tick count ≤ 6.\n */\nexport function niceHourTicks(maxHours: number): number[] {\n if (maxHours <= 0) return [0, 4, 8, 12, 16];\n const steps = [0.25, 0.5, 1, 2, 4, 6, 8, 12, 24, 48, 72, 96, 168];\n const step = steps.find(s => Math.ceil(maxHours / s) <= 6) ?? 168;\n const top = Math.ceil(maxHours / step) * step;\n const ticks: number[] = [];\n for (let v = 0; v <= top + 0.001; v += step) ticks.push(v);\n return ticks;\n}\n\n/**\n * Generate integer Y-axis ticks for count-based DORA charts.\n * Picks a step size that keeps tick count ≤ 6, minimum step of 1.\n */\nexport function niceCountTicks(maxCount: number): number[] {\n if (maxCount <= 0) return [0, 1, 2, 3, 4, 5];\n const step = Math.max(1, Math.ceil(maxCount / 5));\n const top = Math.ceil(maxCount / step) * step;\n const ticks: number[] = [];\n for (let v = 0; v <= top + 0.001; v += step) ticks.push(v);\n return ticks;\n}\n"],"names":[],"mappings":"AAIO,SAAS,cAAc,QAAA,EAA4B;AACxD,EAAA,IAAI,QAAA,IAAY,GAAG,OAAO,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,IAAI,EAAE,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,EAAM,GAAA,EAAK,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,IAAI,GAAG,CAAA;AAChE,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,IAAA,CAAK,KAAK,QAAA,GAAW,CAAC,CAAA,IAAK,CAAC,CAAA,IAAK,GAAA;AAC9D,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,QAAA,GAAW,IAAI,CAAA,GAAI,IAAA;AACzC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,IAAK,GAAA,GAAM,MAAO,CAAA,IAAK,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA;AACzD,EAAA,OAAO,KAAA;AACT;AAMO,SAAS,eAAe,QAAA,EAA4B;AACzD,EAAA,IAAI,QAAA,IAAY,GAAG,OAAO,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAC3C,EAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,IAAA,CAAK,QAAA,GAAW,CAAC,CAAC,CAAA;AAChD,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,QAAA,GAAW,IAAI,CAAA,GAAI,IAAA;AACzC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,IAAK,GAAA,GAAM,MAAO,CAAA,IAAK,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA;AACzD,EAAA,OAAO,KAAA;AACT;;;;"}
@@ -4,6 +4,7 @@ import { useApi } from '@backstage/core-plugin-api';
4
4
  import { useEntity } from '@backstage/plugin-catalog-react';
5
5
  import { InfoCard } from '@backstage/core-components';
6
6
  import { doraMetricsApiRef } from '../api/types.esm.js';
7
+ import { niceHourTicks, niceCountTicks } from '../api/chartUtils.esm.js';
7
8
  import { RatingBadge } from './ui/badge.esm.js';
8
9
  import { Card, CardLabel, CardDescription, CardFooter } from './ui/card.esm.js';
9
10
  import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './ui/select.esm.js';
@@ -310,6 +311,7 @@ function DetailedChart({
310
311
  color,
311
312
  type,
312
313
  formatValue,
314
+ tickUnit,
313
315
  prs,
314
316
  days,
315
317
  hoveredPrNumber,
@@ -324,9 +326,12 @@ function DetailedChart({
324
326
  const PAD = { top: 16, right: 16, bottom: 36, left: 56 };
325
327
  const cW = W - PAD.left - PAD.right;
326
328
  const cH = H - PAD.top - PAD.bottom;
327
- const dataMax = Math.max(...values, 0.01);
328
- const dataMin = type === "line" ? Math.min(...values, 0) : 0;
329
- const dataRange = dataMax - dataMin || dataMax || 1;
329
+ const prMaxDuration = prs && prs.length > 0 ? Math.max(...prs.map((p) => p.durationHours)) : 0;
330
+ const rawDataMax = Math.max(...values.filter((v) => v > 0), prMaxDuration, 0.01);
331
+ const yTicks = tickUnit === "hours" ? niceHourTicks(rawDataMax) : tickUnit === "count" ? niceCountTicks(rawDataMax) : [0, 0.25, 0.5, 0.75, 1].map((t) => t * rawDataMax);
332
+ const dataMin = 0;
333
+ const dataMax = yTicks[yTicks.length - 1];
334
+ const dataRange = dataMax - dataMin || 1;
330
335
  const yScale = (v) => cH - (v - dataMin) / dataRange * cH;
331
336
  const cutoffMs = Date.now() - days * 24 * 60 * 60 * 1e3;
332
337
  const rangeMs = days * 24 * 60 * 60 * 1e3;
@@ -337,7 +342,6 @@ function DetailedChart({
337
342
  const areaPath = pts.length > 1 ? `${linePath} L${pts[pts.length - 1][0]},${PAD.top + cH} L${pts[0][0]},${PAD.top + cH} Z` : "";
338
343
  const gap = 6;
339
344
  const barW = values.length > 1 ? (cW - gap * (values.length - 1)) / values.length : cW;
340
- const yTicks = [0, 0.25, 0.5, 0.75, 1].map((t) => dataMin + t * dataRange);
341
345
  const gridColor = isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.05)";
342
346
  const axisColor = isDark ? "#3f3f46" : "#d4d4d8";
343
347
  const labelColor = isDark ? "#52525b" : "#a1a1aa";
@@ -399,7 +403,7 @@ function DetailedChart({
399
403
  opacity: i === hoverIdx ? 0.95 : 0.4 + i / Math.max(values.length - 1, 1) * 0.45
400
404
  }
401
405
  );
402
- }) : /* @__PURE__ */ React.createElement(React.Fragment, null, areaPath && /* @__PURE__ */ React.createElement("path", { d: areaPath, fill: `url(#${gradId})` }), /* @__PURE__ */ React.createElement("path", { d: linePath, fill: "none", stroke: color, strokeWidth: 2.5, strokeLinejoin: "round", strokeLinecap: "round" }), pts.map(([x, y], i) => /* @__PURE__ */ React.createElement(
406
+ }) : /* @__PURE__ */ React.createElement(React.Fragment, null, !prs && areaPath && /* @__PURE__ */ React.createElement("path", { d: areaPath, fill: `url(#${gradId})` }), !prs && /* @__PURE__ */ React.createElement("path", { d: linePath, fill: "none", stroke: color, strokeWidth: 2, strokeLinejoin: "round", strokeLinecap: "round" }), !prs && pts.map(([x, y], i) => values[i] > 0 && /* @__PURE__ */ React.createElement(
403
407
  "circle",
404
408
  {
405
409
  key: i,
@@ -419,7 +423,7 @@ function DetailedChart({
419
423
  const rawPy = PAD.top + yScale(pr.durationHours);
420
424
  const py = Math.max(PAD.top + 4, Math.min(PAD.top + cH - 4, rawPy));
421
425
  const isHov = pr.number === hoveredPrNumber;
422
- const trendPt = pts[bIdx];
426
+ pts[bIdx];
423
427
  return /* @__PURE__ */ React.createElement(
424
428
  "g",
425
429
  {
@@ -443,19 +447,6 @@ function DetailedChart({
443
447
  onPrHover?.(null);
444
448
  }
445
449
  },
446
- trendPt && /* @__PURE__ */ React.createElement(
447
- "line",
448
- {
449
- x1: px,
450
- y1: py,
451
- x2: trendPt[0],
452
- y2: trendPt[1],
453
- stroke: color,
454
- strokeWidth: isHov ? 1 : 0.5,
455
- strokeDasharray: "2 3",
456
- opacity: isHov ? 0.5 : 0.2
457
- }
458
- ),
459
450
  /* @__PURE__ */ React.createElement("circle", { cx: px, cy: py, r: isHov ? 11 : 7, fill: color, opacity: isHov ? 0.2 : 0.1 }),
460
451
  /* @__PURE__ */ React.createElement(
461
452
  "circle",
@@ -550,7 +541,7 @@ function DetailedOverlay({
550
541
  if (el) el.scrollIntoView({ behavior: "smooth", block: "nearest" });
551
542
  }
552
543
  }, [hoveredPrNumber]);
553
- const { title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, weekLabels, bucketMidMs, prs, prListLabel } = data;
544
+ const { title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, tickUnit, weekLabels, bucketMidMs, prs, prListLabel } = data;
554
545
  const isDeployFreq = sparklineType === "bar";
555
546
  const displayValue = metric.unit === "hours" ? formatDuration(metric.value) : String(metric.value);
556
547
  const displayUnit = metric.unit === "hours" ? "" : metric.unit;
@@ -633,6 +624,7 @@ function DetailedOverlay({
633
624
  bucketMidMs,
634
625
  color: sparklineColor,
635
626
  type: sparklineType,
627
+ tickUnit,
636
628
  formatValue: formatVal,
637
629
  prs: isDeployFreq ? void 0 : prs,
638
630
  days,
@@ -989,7 +981,7 @@ function DoraMetricsContent() {
989
981
  const cfrData = history?.map((h) => h.changeFailureRate ?? 0) ?? [];
990
982
  const mttrData = history?.map((h) => h.mttrHours ?? 0) ?? [];
991
983
  const bmMs = history?.map((h) => h.bucketMidMs) ?? [];
992
- const mkExpand = (title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, prs, prListLabel) => () => setExpanded({
984
+ const mkExpand = (title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, prs, prListLabel, tickUnit) => () => setExpanded({
993
985
  title,
994
986
  metric,
995
987
  description,
@@ -997,11 +989,27 @@ function DoraMetricsContent() {
997
989
  sparklineValues,
998
990
  sparklineType,
999
991
  sparklineColor,
992
+ tickUnit,
1000
993
  weekLabels: wkLabels,
1001
994
  bucketMidMs: bmMs,
1002
995
  prs,
1003
996
  prListLabel
1004
997
  });
998
+ const hotfixSparkData = bmMs.map(() => 0);
999
+ if (bmMs.length > 0 && metrics?.numberOfHotfixes?.slowestPRs) {
1000
+ for (const pr of metrics.numberOfHotfixes.slowestPRs) {
1001
+ const t = new Date(pr.mergedAt).getTime();
1002
+ let bestIdx = 0, bestDist = Infinity;
1003
+ bmMs.forEach((mid, i) => {
1004
+ const d = Math.abs(t - mid);
1005
+ if (d < bestDist) {
1006
+ bestDist = d;
1007
+ bestIdx = i;
1008
+ }
1009
+ });
1010
+ hotfixSparkData[bestIdx]++;
1011
+ }
1012
+ }
1005
1013
  return /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: 12 } }, /* @__PURE__ */ React.createElement(
1006
1014
  MetricCard,
1007
1015
  {
@@ -1020,7 +1028,9 @@ function DoraMetricsContent() {
1020
1028
  deployData,
1021
1029
  "bar",
1022
1030
  "#FA6400",
1023
- metrics.deploymentFrequency.slowestPRs
1031
+ metrics.deploymentFrequency.slowestPRs,
1032
+ void 0,
1033
+ "count"
1024
1034
  )
1025
1035
  }
1026
1036
  ), /* @__PURE__ */ React.createElement(
@@ -1042,7 +1052,9 @@ function DoraMetricsContent() {
1042
1052
  leadData,
1043
1053
  "line",
1044
1054
  "#818cf8",
1045
- metrics.leadTime.slowestPRs
1055
+ metrics.leadTime.slowestPRs,
1056
+ void 0,
1057
+ "hours"
1046
1058
  )
1047
1059
  }
1048
1060
  ), metrics.changeFailureRate !== null ? /* @__PURE__ */ React.createElement(
@@ -1063,7 +1075,10 @@ function DoraMetricsContent() {
1063
1075
  true,
1064
1076
  cfrData,
1065
1077
  "line",
1066
- "#f87171"
1078
+ "#f87171",
1079
+ void 0,
1080
+ void 0,
1081
+ "count"
1067
1082
  )
1068
1083
  }
1069
1084
  ) : /* @__PURE__ */ React.createElement(NaCard, { title: "Change Failure Rate", description: "Only tracked on production branches" }), metrics.mttr !== null ? /* @__PURE__ */ React.createElement(
@@ -1085,7 +1100,9 @@ function DoraMetricsContent() {
1085
1100
  mttrData,
1086
1101
  "line",
1087
1102
  "#fbbf24",
1088
- metrics.mttr.slowestPRs
1103
+ metrics.mttr.slowestPRs,
1104
+ void 0,
1105
+ "hours"
1089
1106
  )
1090
1107
  }
1091
1108
  ) : /* @__PURE__ */ React.createElement(NaCard, { title: "Mean Time to Restore", description: "Only tracked on production branches" }), metrics.numberOfHotfixes !== null ? /* @__PURE__ */ React.createElement(
@@ -1101,11 +1118,12 @@ function DoraMetricsContent() {
1101
1118
  metrics.numberOfHotfixes,
1102
1119
  `PRs labeled '${selectedEnv?.label ?? "hotfix"}' merged to production`,
1103
1120
  true,
1104
- [],
1121
+ hotfixSparkData,
1105
1122
  "bar",
1106
1123
  "#f87171",
1107
1124
  metrics.numberOfHotfixes.slowestPRs,
1108
- "All hotfixes"
1125
+ "All hotfixes",
1126
+ "count"
1109
1127
  )
1110
1128
  }
1111
1129
  ) : /* @__PURE__ */ React.createElement(NaCard, { title: "Hotfixes to Production", description: "Only tracked on production branches" }));
@@ -1 +1 @@
1
- {"version":3,"file":"DoraMetricsContent.esm.js","sources":["../../src/components/DoraMetricsContent.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport { useTheme } from '@material-ui/core/styles';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { InfoCard } from '@backstage/core-components';\nimport { doraMetricsApiRef } from '../api/types';\nimport type { DoraEnvironment, DoraHistoryPoint, DoraMetrics, DoraMetricValue, DoraTargets, PrDetail } from '../api/types';\nimport { RatingBadge } from './ui/badge';\nimport { Card, CardLabel, CardFooter, CardDescription } from './ui/card';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from './ui/select';\nimport { ExternalLink } from 'lucide-react';\n\nconst ANNOTATION_PROJECT_SLUG = 'github.com/project-slug';\n/** Override the global environments list for this specific entity. JSON array of DoraEnvironment objects. */\nconst ANNOTATION_ENVIRONMENTS = 'dora-metrics/environments';\n/** Override the global performance targets for this specific entity. JSON object matching DoraTargets. */\nconst ANNOTATION_TARGETS = 'dora-metrics/targets';\n\n/** Parse entity annotation overrides. Returns undefined for malformed JSON to fail gracefully. */\nfunction parseAnnotationJson<T>(raw: string | undefined): T | undefined {\n if (!raw) return undefined;\n try { return JSON.parse(raw) as T; } catch { return undefined; }\n}\n\nconst DATE_RANGE_OPTIONS = [\n { value: '7', label: 'Last 7 days' },\n { value: '14', label: 'Last 14 days' },\n { value: '30', label: 'Last 30 days' },\n { value: '60', label: 'Last 60 days' },\n { value: '90', label: 'Last 90 days' },\n];\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction formatDuration(hours: number): string {\n const totalMinutes = Math.round(hours * 60);\n const d = Math.floor(totalMinutes / (24 * 60));\n const h = Math.floor((totalMinutes % (24 * 60)) / 60);\n const m = totalMinutes % 60;\n if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`;\n if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`;\n return `${m}m`;\n}\n\n// Red → Orange → Yellow → Lime → Green gradient (slowest to fastest)\nconst DURATION_GRADIENT = ['#f87171', '#fb923c', '#fbbf24', '#a3e635', '#4ade80'];\n\nfunction durationColor(index: number, total: number): string {\n if (total <= 1) return DURATION_GRADIENT[0];\n const step = (DURATION_GRADIENT.length - 1) / (total - 1);\n return DURATION_GRADIENT[Math.round(index * step)];\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\n// Period-over-period delta — compares last bucket vs second-to-last bucket\nfunction buildDeltaLabel(\n values: number[],\n unit: string,\n lowerIsBetter: boolean,\n): { text: string; tooltip: string; good: boolean } | null {\n if (values.length < 2) return null;\n const curr = values[values.length - 1];\n const prev = values[values.length - 2];\n const diff = curr - prev;\n if (Math.abs(diff) < 0.001) return null;\n const good = lowerIsBetter ? diff < 0 : diff > 0;\n const arrow = diff > 0 ? '↑' : '↓';\n\n const fmt = (v: number) =>\n unit === 'hours' ? formatDuration(v) :\n unit === '%' ? `${Math.round(v * 10) / 10}%` :\n unit === 'per week' ? `${Math.round(v * 10) / 10}/wk` :\n `${Math.round(v * 10) / 10} ${unit}`;\n\n const direction = good ? 'improving' : 'worsening';\n return {\n text: `${arrow} ${fmt(Math.abs(diff))} ${direction}`,\n tooltip: `Latest period: ${fmt(curr)} · Previous period: ${fmt(prev)}\\nEach period = one time bucket (~1/7th of your selected date range)`,\n good,\n };\n}\n\n// ─── Loading overlay ────────────────────────────────────────────────────────\n\nconst LOADING_MESSAGES = [\n 'Establishing routes…',\n 'Syncing catalog…',\n 'Loading plugins…',\n 'Fetching PR data…',\n 'Reading entity graph…',\n];\nconst STAGES = ['FETCH', 'PARSE', 'SCORE', 'RENDER'] as const;\nconst FONT_IMPACT = '\"Impact\",\"Haettenschweiler\",\"Franklin Gothic Heavy\",\"Arial Black\",sans-serif';\nconst FONT_MONO = '\"JetBrains Mono\",\"Fira Code\",\"Consolas\",monospace';\n\nfunction DoraLoadingOverlay() {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n const [activeStage, setActiveStage] = useState(0);\n const [msgKey, setMsgKey] = useState(0);\n const [msgIdx, setMsgIdx] = useState(0);\n\n useEffect(() => {\n const st = setInterval(() => setActiveStage(s => (s + 1) % STAGES.length), 800);\n return () => clearInterval(st);\n }, []);\n\n useEffect(() => {\n const mt = setInterval(() => { setMsgIdx(i => (i + 1) % LOADING_MESSAGES.length); setMsgKey(k => k + 1); }, 2200);\n return () => clearInterval(mt);\n }, []);\n\n const textShadow = isDark\n ? '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 #5A1800, 12px 12px 0 rgba(0,0,0,0.55), 0 0 60px rgba(250,100,0,0.45)'\n : '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 rgba(80,20,0,0.28), 0 0 32px rgba(250,100,0,0.22)';\n\n const mutedColor = isDark ? '#3f3f46' : '#a1a1aa';\n const subtitleColor = isDark ? '#52525b' : '#71717a';\n const borderColor = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n\n return (\n <>\n {/* Frosted glass backdrop — blurs whatever is behind */}\n <div aria-hidden style={{\n position: 'fixed', inset: 0, zIndex: 900,\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n background: isDark ? 'rgba(6,6,9,0.65)' : 'rgba(253,252,251,0.70)',\n }} />\n\n {/* Centered card */}\n <div style={{\n position: 'fixed', zIndex: 901,\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n display: 'flex', flexDirection: 'column', alignItems: 'center',\n padding: '48px 56px 40px',\n borderRadius: 20,\n background: isDark ? 'rgba(9,9,12,0.82)' : 'rgba(255,255,255,0.88)',\n border: `1px solid ${borderColor}`,\n boxShadow: isDark\n ? '0 0 0 1px rgba(250,100,0,0.06), 0 32px 80px rgba(0,0,0,0.65)'\n : '0 32px 80px rgba(0,0,0,0.12)',\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n animation: 'dlsCardIn 0.35s cubic-bezier(0.34,1.2,0.64,1) both',\n overflow: 'visible',\n }}>\n\n {/* Breathing ambient glow — inside card */}\n <div aria-hidden style={{\n position: 'absolute', width: 500, height: 360,\n left: '50%', top: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n background: `radial-gradient(ellipse at center, ${isDark ? 'rgba(250,100,0,0.08)' : 'rgba(250,100,0,0.05)'} 0%, transparent 70%)`,\n animation: 'dlsBreath 3.2s ease-in-out infinite',\n pointerEvents: 'none', borderRadius: 20,\n }} />\n\n {/* DORA wordmark */}\n <div style={{ display: 'flex', lineHeight: 1, marginBottom: 6 }}>\n {['D','O','R','A'].map((letter, i) => (\n <span key={i} style={{\n fontFamily: FONT_IMPACT, fontWeight: 900, fontSize: 110,\n color: '#FA6400', letterSpacing: '0.04em', display: 'inline-block',\n transform: 'skewX(-6deg)', textShadow,\n WebkitTextStroke: '0.5px #C24E00',\n animation: `dlsLetterDrop 0.6s cubic-bezier(0.34,1.45,0.64,1) ${i * 0.1}s both`,\n }}>\n {letter}\n </span>\n ))}\n </div>\n\n {/* Subtitle */}\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 13, fontWeight: 400,\n letterSpacing: '0.06em', color: subtitleColor, marginBottom: 32,\n animation: 'dlsFadeUp 0.4s ease 0.55s both' }}>\n Metrics\n </span>\n\n {/* Pipeline stages */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 0, marginBottom: 20, animation: 'dlsFadeUp 0.4s ease 0.7s both' }}>\n {STAGES.map((stage, i) => {\n const isActive = i === activeStage;\n const isComplete = i < activeStage;\n return (\n <div key={stage} style={{ display: 'flex', alignItems: 'center', gap: 0 }}>\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, width: 64 }}>\n <div style={{ position: 'relative', width: 12, height: 12 }}>\n {isActive && (\n <div style={{ position: 'absolute', inset: -6, borderRadius: '50%',\n border: '1.5px solid rgba(250,100,0,0.5)', animation: 'dlsPulse 1s ease-out infinite' }} />\n )}\n <div style={{\n width: 12, height: 12, borderRadius: '50%',\n background: (isActive || isComplete) ? '#FA6400' : (isDark ? '#27272a' : '#e4e4e7'),\n border: `2px solid ${(isActive || isComplete) ? '#C24E00' : (isDark ? '#3f3f46' : '#d4d4d8')}`,\n boxShadow: isActive ? '0 0 14px rgba(250,100,0,0.7)' : 'none',\n transition: 'background 0.3s, box-shadow 0.3s',\n }} />\n </div>\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 8, fontWeight: 700,\n letterSpacing: '0.12em', textTransform: 'uppercase',\n color: isActive ? '#FA6400' : isComplete ? mutedColor : mutedColor,\n transition: 'color 0.3s' }}>\n {stage}\n </span>\n </div>\n {i < STAGES.length - 1 && (\n <div style={{ width: 32, height: 2, marginBottom: 14, position: 'relative', overflow: 'hidden',\n background: isDark ? '#27272a' : '#e4e4e7', borderRadius: 2 }}>\n <div style={{\n position: 'absolute', inset: 0, borderRadius: 2, background: '#FA6400',\n transformOrigin: 'left center',\n transform: `scaleX(${i < activeStage ? 1 : isActive ? 0.5 : 0})`,\n transition: 'transform 0.4s ease',\n }} />\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Status message */}\n <span key={msgKey} style={{ fontFamily: FONT_MONO, fontSize: 11,\n color: mutedColor, letterSpacing: '0.04em', animation: 'dlsFadeUp 0.3s ease both' }}>\n {LOADING_MESSAGES[msgIdx]}\n </span>\n\n </div>{/* end card */}\n\n <style>{`\n @keyframes dlsLetterDrop {\n from { opacity: 0; transform: skewX(-6deg) translateY(-32px) scale(1.1); }\n 65% { transform: skewX(-6deg) translateY(6px) scale(0.95); }\n to { opacity: 1; transform: skewX(-6deg) translateY(0) scale(1); }\n }\n @keyframes dlsFadeUp {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes dlsBreath {\n 0%, 100% { transform: translateX(-50%) translateY(-50%) scale(0.85); opacity: 0.6; }\n 50% { transform: translateX(-50%) translateY(-50%) scale(1.2); opacity: 1; }\n }\n @keyframes dlsPulse {\n from { transform: scale(0.6); opacity: 0.9; }\n to { transform: scale(2.2); opacity: 0; }\n }\n @keyframes dlsCardIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Compact sparkline (with hover tooltip + date axis) ────────────────────\n\nfunction CompactSparkline({\n values,\n weekLabels,\n color,\n type,\n formatValue,\n height = 36,\n}: {\n values: number[];\n weekLabels: string[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n height?: number;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n\n const VW = 400; // viewBox units\n const mutedBorder = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';\n const tooltipBg = isDark ? '#1c1c20' : '#ffffff';\n const tooltipBdr = isDark ? '#3f3f46' : '#e4e4e7';\n const tooltipText = isDark ? '#ededef' : '#111114';\n const font = 'Inter,system-ui,sans-serif';\n\n const handleMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left) / rect.width;\n setHoverIdx(Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1)))));\n };\n\n if (type === 'bar') {\n const max = Math.max(...values, 1);\n const gap = 4;\n const barW = (VW - gap * (values.length - 1)) / values.length;\n\n const hoverX = hoverIdx !== null\n ? hoverIdx * (barW + gap) + barW / 2\n : null;\n const tooltipX = hoverX !== null ? Math.min(hoverX - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n {values.map((v, i) => {\n const h = Math.max(2, (v / max) * (height - 4));\n return (\n <rect key={i} x={i * (barW + gap)} y={height - h} width={barW} height={h} rx={1.5}\n fill={color} opacity={i === hoverIdx ? 1 : 0.3 + (i / values.length) * 0.55} />\n );\n })}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverIdx !== null && hoverX !== null && (\n <>\n <rect x={tooltipX} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n }\n\n if (values.length < 2) return null;\n const max = Math.max(...values, 0.01);\n const min = Math.min(...values);\n const range = max - min || max || 1;\n const pad = 3;\n const pts = values.map((v, i): [number, number] => [\n (i / (values.length - 1)) * (VW - pad * 2) + pad,\n (height - pad * 2) - ((v - min) / range) * (height - pad * 2 - 2) + pad,\n ]);\n const d = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const area = `${d} L${pts[pts.length-1][0]},${height} L${pts[0][0]},${height} Z`;\n const hoverPt = hoverIdx !== null ? pts[hoverIdx] : null;\n const tooltipX2 = hoverPt ? Math.min(hoverPt[0] - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n <path d={area} fill={color} opacity={0.07} />\n <path d={d} fill=\"none\" stroke={color} strokeWidth={1.5} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n {pts.map(([x, y], i) => (\n <circle key={i} cx={x} cy={y} r={i === hoverIdx ? 3.5 : i === pts.length - 1 ? 2.5 : 0} fill={color} />\n ))}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverPt && hoverIdx !== null && (\n <>\n <line x1={hoverPt[0]} y1={0} x2={hoverPt[0]} y2={height} stroke={color} strokeWidth={1} strokeDasharray=\"2 2\" opacity={0.4} />\n <rect x={tooltipX2} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX2 + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n}\n\n// ─── Detailed interactive chart ────────────────────────────────────────────\n\ninterface ChartTooltipState {\n x: number;\n y: number;\n primary: string;\n secondary?: string;\n}\n\nfunction DetailedChart({\n values,\n weekLabels,\n bucketMidMs,\n color,\n type,\n formatValue,\n prs,\n days,\n hoveredPrNumber,\n onPrHover,\n}: {\n values: number[];\n weekLabels: string[];\n bucketMidMs: number[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n prs?: PrDetail[];\n days: number;\n hoveredPrNumber?: number | null;\n onPrHover?: (num: number | null) => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n const [tooltip, setTooltip] = useState<ChartTooltipState | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const W = 800, H = 260;\n const PAD = { top: 16, right: 16, bottom: 36, left: 56 };\n const cW = W - PAD.left - PAD.right;\n const cH = H - PAD.top - PAD.bottom;\n\n // Y scale: based on bucket values only so the trend line is clearly readable.\n // PR dots that fall outside this range are rendered clamped to chart area.\n const dataMax = Math.max(...values, 0.01);\n const dataMin = type === 'line' ? Math.min(...values, 0) : 0;\n const dataRange = dataMax - dataMin || dataMax || 1;\n const yScale = (v: number) => cH - ((v - dataMin) / dataRange) * cH;\n\n // Shared timestamp-based x-axis\n const cutoffMs = Date.now() - days * 24 * 60 * 60 * 1000;\n const rangeMs = days * 24 * 60 * 60 * 1000;\n const xTime = (ms: number) => Math.max(0, Math.min(cW, ((ms - cutoffMs) / rangeMs) * cW));\n\n const xIdx = (i: number) => bucketMidMs.length === values.length\n ? xTime(bucketMidMs[i])\n : (values.length > 1 ? (i / (values.length - 1)) * cW : cW / 2);\n\n const pts: [number, number][] = values.map((v, i) => [PAD.left + xIdx(i), PAD.top + yScale(v)]);\n const linePath = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const areaPath = pts.length > 1\n ? `${linePath} L${pts[pts.length-1][0]},${PAD.top+cH} L${pts[0][0]},${PAD.top+cH} Z`\n : '';\n\n const gap = 6;\n const barW = values.length > 1 ? (cW - gap * (values.length - 1)) / values.length : cW;\n\n const yTicks = [0, 0.25, 0.5, 0.75, 1].map(t => dataMin + t * dataRange);\n const gridColor = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)';\n const axisColor = isDark ? '#3f3f46' : '#d4d4d8';\n const labelColor = isDark ? '#52525b' : '#a1a1aa';\n const font = 'Inter,system-ui,sans-serif';\n const gradId = `dg_${color.replace('#','')}`;\n\n // Find the nearest bucket index for a given timestamp\n const nearestBucket = (ms: number): number => {\n if (bucketMidMs.length === 0) return 0;\n let best = 0, bestDist = Infinity;\n bucketMidMs.forEach((mid, i) => {\n const d = Math.abs(ms - mid);\n if (d < bestDist) { bestDist = d; best = i; }\n });\n return best;\n };\n\n const handleSvgMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left - PAD.left * (rect.width / W)) / (rect.width * cW / W);\n const idx = Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1))));\n setHoverIdx(idx);\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y, primary: formatValue(values[idx]), secondary: weekLabels[idx] });\n };\n\n return (\n <div ref={containerRef} style={{ position: 'relative' }}>\n <svg viewBox={`0 0 ${W} ${H}`} width=\"100%\" style={{ display: 'block' }}\n onMouseMove={handleSvgMouseMove}\n onMouseLeave={() => { setHoverIdx(null); setTooltip(null); }}>\n <defs>\n <linearGradient id={gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.28} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n {/* Clip PR dots to the chart area */}\n <clipPath id={`prClip_${gradId}`}>\n <rect x={PAD.left} y={PAD.top - 8} width={cW} height={cH + 16} />\n </clipPath>\n </defs>\n\n {/* Grid + Y-axis */}\n {yTicks.map((v, i) => {\n const y = PAD.top + yScale(v);\n return (\n <g key={i}>\n {i > 0 && <line x1={PAD.left} y1={y} x2={PAD.left+cW} y2={y} stroke={gridColor} strokeWidth={1} strokeDasharray=\"3 4\" />}\n <text x={PAD.left - 6} y={y + 4} textAnchor=\"end\" fill={labelColor} fontSize={10} fontFamily={font}>\n {formatValue(v)}\n </text>\n </g>\n );\n })}\n <line x1={PAD.left} y1={PAD.top+cH} x2={PAD.left+cW} y2={PAD.top+cH} stroke={axisColor} strokeWidth={1} />\n\n {/* Chart body */}\n {type === 'bar' ? (\n values.map((v, i) => {\n const bH = Math.max(2, ((v - dataMin) / dataRange) * cH);\n const x = PAD.left + i * (barW + gap);\n return (\n <rect key={i} x={x} y={PAD.top+cH-bH} width={barW} height={bH} rx={3}\n fill={color} opacity={i === hoverIdx ? 0.95 : 0.4 + (i / Math.max(values.length - 1, 1)) * 0.45} />\n );\n })\n ) : (\n <>\n {areaPath && <path d={areaPath} fill={`url(#${gradId})`} />}\n <path d={linePath} fill=\"none\" stroke={color} strokeWidth={2.5} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n {pts.map(([x, y], i) => (\n <circle key={i} cx={x} cy={y}\n r={i === hoverIdx ? 5.5 : 4}\n fill={isDark ? '#0f0f12' : '#ffffff'} stroke={color}\n strokeWidth={i === hoverIdx ? 2.5 : 1.5} />\n ))}\n </>\n )}\n\n {/* PR data-point dots — x at bucket midpoint, y at actual duration (clamped to chart) */}\n {prs && type === 'line' && (\n <g clipPath={`url(#prClip_${gradId})`}>\n {prs.map((pr, dotIdx) => {\n const mergedMs = new Date(pr.mergedAt).getTime();\n const bIdx = nearestBucket(mergedMs);\n // Small deterministic jitter within the bucket to avoid overlap\n const jitter = ((pr.number * 17 + dotIdx * 11) % 13 - 6) * 5;\n const px = PAD.left + xIdx(bIdx) + jitter;\n // Clamp y: PR may be faster or slower than bucket avg; always visible\n const rawPy = PAD.top + yScale(pr.durationHours);\n const py = Math.max(PAD.top + 4, Math.min(PAD.top + cH - 4, rawPy));\n const isHov = pr.number === hoveredPrNumber;\n\n // Thin connector from dot to the bucket trend point\n const trendPt = pts[bIdx];\n\n return (\n <g key={pr.number} style={{ cursor: 'pointer' }}\n onMouseEnter={e => {\n e.stopPropagation();\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y,\n primary: `#${pr.number}: ${pr.title}`,\n secondary: `${formatValue(pr.durationHours)} · ${new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}` });\n onPrHover?.(pr.number);\n }}\n onMouseLeave={() => { setTooltip(null); onPrHover?.(null); }}>\n {trendPt && (\n <line x1={px} y1={py} x2={trendPt[0]} y2={trendPt[1]}\n stroke={color} strokeWidth={isHov ? 1 : 0.5}\n strokeDasharray=\"2 3\" opacity={isHov ? 0.5 : 0.2} />\n )}\n <circle cx={px} cy={py} r={isHov ? 11 : 7} fill={color} opacity={isHov ? 0.2 : 0.1} />\n <circle cx={px} cy={py} r={isHov ? 5.5 : 3.5}\n fill={isHov ? color : (isDark ? '#1a1a20' : '#fff')}\n stroke={color} strokeWidth={isHov ? 0 : 1.5}\n opacity={isHov ? 1 : 0.8} />\n </g>\n );\n })}\n </g>\n )}\n\n {/* Hover crosshair */}\n {hoverIdx !== null && type === 'line' && pts[hoverIdx] && (\n <>\n <line x1={pts[hoverIdx][0]} y1={PAD.top} x2={pts[hoverIdx][0]} y2={PAD.top+cH}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.3} />\n <line x1={PAD.left} y1={pts[hoverIdx][1]} x2={PAD.left+cW} y2={pts[hoverIdx][1]}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.2} />\n </>\n )}\n\n {/* X-axis labels */}\n {weekLabels.map((lbl, i) => {\n const total = weekLabels.length;\n const step = Math.max(1, Math.floor(total / 5));\n if (i !== 0 && i !== total - 1 && i % step !== 0) return null;\n const x = type === 'bar'\n ? PAD.left + i * (barW + gap) + barW / 2\n : PAD.left + xIdx(i);\n return (\n <text key={i} x={x} y={H - 8} textAnchor=\"middle\" fill={labelColor} fontSize={10} fontFamily={font}>\n {lbl}\n </text>\n );\n })}\n </svg>\n\n {/* Absolute tooltip — positioned relative to the chart container */}\n {tooltip && (() => {\n const TW = 220;\n const cW2 = containerRef.current?.offsetWidth ?? 800;\n const nearRight = tooltip.x + TW + 12 > cW2;\n return (\n <div style={{\n position: 'absolute',\n left: nearRight ? tooltip.x - TW - 8 : tooltip.x + 8,\n top: tooltip.y - 36,\n zIndex: 9999, pointerEvents: 'none',\n background: isDark ? '#18181b' : '#ffffff',\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}`,\n borderRadius: 7, padding: '7px 10px',\n boxShadow: isDark ? '0 6px 20px rgba(0,0,0,0.55)' : '0 6px 20px rgba(0,0,0,0.10)',\n width: TW,\n }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: isDark ? '#ededef' : '#111114',\n fontFamily: font, lineHeight: 1.4 }}>\n {tooltip.primary}\n </div>\n {tooltip.secondary && (\n <div style={{ fontSize: 11, color: isDark ? '#71717a' : '#a1a1aa', fontFamily: font, marginTop: 2 }}>\n {tooltip.secondary}\n </div>\n )}\n </div>\n );\n })()}\n </div>\n );\n}\n\n// ─── Detailed overlay ──────────────────────────────────────────────────────\n\ninterface ExpandedCardData {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter: boolean;\n sparklineValues: number[];\n sparklineType: 'bar' | 'line';\n sparklineColor: string;\n weekLabels: string[];\n bucketMidMs: number[];\n prs?: PrDetail[];\n /** Override the section header above the PR list (default: \"All deployments\"). */\n prListLabel?: string;\n}\n\nfunction DetailedOverlay({\n data,\n days,\n onClose,\n}: {\n data: ExpandedCardData;\n days: number;\n onClose: () => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoveredPrNumber, setHoveredPrNumber] = useState<number | null>(null);\n const prRowRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n // Auto-scroll to the highlighted PR row when hover comes from the chart\n useEffect(() => {\n if (hoveredPrNumber !== null) {\n const el = prRowRefs.current.get(hoveredPrNumber);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, [hoveredPrNumber]);\n\n const { title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, weekLabels, bucketMidMs, prs, prListLabel } = data;\n const isDeployFreq = sparklineType === 'bar';\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : String(metric.value);\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n const borderColor = isDark ? '#27272a' : '#e4e4e7';\n const mutedColor = isDark ? '#52525b' : '#a1a1aa';\n const targetLabel = lowerIsBetter\n ? `Target: < ${metric.unit === 'hours' ? formatDuration(metric.target) : metric.target} ${displayUnit}`\n : `Target: ≥ ${metric.target} ${displayUnit}`;\n\n // Group deployment PRs by date (for the date table)\n const prsByDate = isDeployFreq && prs ? prs.reduce((acc, pr) => {\n const date = new Date(pr.mergedAt).toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });\n if (!acc[date]) acc[date] = [];\n acc[date].push(pr);\n return acc;\n }, {} as Record<string, PrDetail[]>) : {};\n const sortedDates = Object.keys(prsByDate).sort(\n (a, b) => new Date(prsByDate[b][0].mergedAt).getTime() - new Date(prsByDate[a][0].mergedAt).getTime()\n );\n\n return (\n <>\n {/* Backdrop */}\n <div onClick={onClose} style={{\n position: 'fixed', inset: 0, zIndex: 499,\n background: isDark ? 'rgba(0,0,0,0.6)' : 'rgba(0,0,0,0.3)',\n backdropFilter: 'blur(4px)',\n }} />\n\n {/* Panel */}\n <div style={{\n position: 'fixed',\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n width: 'min(92vw, 960px)',\n maxHeight: 'calc(100vh - 80px)',\n zIndex: 500,\n background: isDark ? '#09090c' : '#fafafa',\n border: `1px solid ${borderColor}`,\n borderRadius: 14,\n display: 'flex', flexDirection: 'column',\n overflow: 'hidden',\n animation: 'detailExpandIn 0.2s cubic-bezier(0.34,1.2,0.64,1)',\n boxShadow: isDark ? '0 24px 64px rgba(0,0,0,0.7)' : '0 24px 64px rgba(0,0,0,0.18)',\n }}>\n {/* Header */}\n <div style={{\n display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',\n padding: '20px 24px 16px',\n borderBottom: `1px solid ${borderColor}`,\n flexShrink: 0,\n }}>\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase', letterSpacing: '0.12em', marginBottom: 8 }}>\n {title} · {weekLabels[0]} – {weekLabels[weekLabels.length - 1]}\n </div>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>\n <span style={{ fontSize: 52, fontWeight: 700, color: theme.palette.text.primary, lineHeight: 1, letterSpacing: '-0.02em' }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 18, color: mutedColor, fontWeight: 500 }}>{displayUnit}</span>\n )}\n <RatingBadge rating={metric.rating} />\n </div>\n <div style={{ fontSize: 12, color: mutedColor, marginTop: 6 }}>\n {description} · <span style={{ fontStyle: 'italic' }}>{targetLabel}</span>\n </div>\n </div>\n <button type=\"button\" onClick={onClose} style={{\n all: 'unset', cursor: 'pointer', width: 30, height: 30,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n borderRadius: '50%', background: isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)',\n color: mutedColor, fontSize: 18, fontWeight: 300, transition: 'all 0.12s', flexShrink: 0,\n }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.1)'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'; }}>\n ✕\n </button>\n </div>\n\n {/* Body — scrollable */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 20 }}>\n\n {/* Chart */}\n {weekLabels.length >= 2 ? (\n <DetailedChart\n values={sparklineValues} weekLabels={weekLabels}\n bucketMidMs={bucketMidMs}\n color={sparklineColor} type={sparklineType}\n formatValue={formatVal} prs={isDeployFreq ? undefined : prs} days={days}\n hoveredPrNumber={hoveredPrNumber} onPrHover={setHoveredPrNumber}\n />\n ) : (\n <div style={{ color: mutedColor, fontSize: 13, textAlign: 'center', padding: '48px 0' }}>\n Not enough data — select a wider date range.\n </div>\n )}\n\n {/* === Deployment Frequency: PRs grouped by date === */}\n {isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 12,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {prListLabel ?? 'All deployments'} · {prs.length} PR{prs.length !== 1 ? 's' : ''}\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {sortedDates.map(date => (\n <div key={date}>\n {/* Date header */}\n <div style={{\n fontSize: 11, fontWeight: 700, color: sparklineColor,\n marginBottom: 6, display: 'flex', alignItems: 'center', gap: 8,\n }}>\n <span>{date}</span>\n <span style={{ color: mutedColor, fontWeight: 500 }}>· {prsByDate[date].length} PR{prsByDate[date].length > 1 ? 's' : ''}</span>\n </div>\n {/* PR rows */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, paddingLeft: 12,\n borderLeft: `2px solid ${sparklineColor}22` }}>\n {prsByDate[date].map(pr => (\n <div key={pr.number} style={{\n display: 'flex', flexDirection: 'column', gap: 5,\n padding: '7px 10px', borderRadius: 7,\n background: isDark ? '#0d0d10' : '#f7f7f9',\n border: `1px solid ${borderColor}`,\n transition: 'background 0.12s',\n }}>\n {/* Row 1: number + title + lead time + link */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: mutedColor, flexShrink: 0, minWidth: 36 }}>\n #{pr.number}\n </span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {formatDuration(pr.durationHours)} lead\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0 }}>\n <ExternalLink size={11} />\n </a>\n </div>\n {/* Row 2: author badge */}\n {pr.author && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>\n {pr.authorAvatar ? (\n <img src={pr.authorAvatar} alt={pr.author}\n style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}` }} />\n ) : (\n <div style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n background: isDark ? '#27272a' : '#e4e4e7',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n fontSize: 8, fontWeight: 700, color: mutedColor }}>\n {pr.author[0].toUpperCase()}\n </div>\n )}\n <a href={`https://github.com/${pr.author}`} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: 10, fontWeight: 500, color: mutedColor,\n textDecoration: 'none', letterSpacing: '0.01em' }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.color = '#FA6400'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.color = mutedColor; }}>\n @{pr.author}\n </a>\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* === Lead Time / MTTR: duration-ranked PR list with hover linking === */}\n {!isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 10,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {title.toLowerCase().includes('restore') ? 'Slowest Hotfix PRs' : 'Slowest PRs'}\n {' '}· hover a row to highlight on chart\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {prs.map((pr, i) => {\n const col = durationColor(i, prs.length);\n const maxDur = prs[0].durationHours;\n const barPct = maxDur > 0 ? (pr.durationHours / maxDur) * 100 : 0;\n const isHov = pr.number === hoveredPrNumber;\n return (\n <div key={pr.number}\n ref={(el) => {\n if (el) prRowRefs.current.set(pr.number, el);\n else prRowRefs.current.delete(pr.number);\n }}\n onMouseEnter={() => setHoveredPrNumber(pr.number)}\n onMouseLeave={() => setHoveredPrNumber(null)}\n style={{\n padding: '8px 12px', borderRadius: 8,\n background: isHov\n ? (isDark ? '#18181f' : '#f0f0ff')\n : (isDark ? '#111114' : '#f4f4f6'),\n border: `1px solid ${isHov ? `${sparklineColor}55` : borderColor}`,\n display: 'flex', flexDirection: 'column', gap: 5,\n transition: 'background 0.12s, border-color 0.12s',\n cursor: 'default',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: col, flexShrink: 0 }}>#{pr.number}</span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0, transition: 'color 0.12s' }}>\n <ExternalLink size={11} />\n </a>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <AnimatedBar widthPct={barPct} color={col} />\n <span style={{ fontSize: 11, fontWeight: 700, color: col, minWidth: 52, textAlign: 'right', flexShrink: 0 }}>\n {formatDuration(pr.durationHours)}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n </div>\n <style>{`\n @keyframes detailExpandIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Animated bar ──────────────────────────────────────────────────────────\n\nfunction AnimatedBar({ widthPct, color }: { widthPct: number; color: string }) {\n const [width, setWidth] = useState(0);\n const ref = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n useEffect(() => {\n const timer = setTimeout(() => setWidth(widthPct), 80);\n return () => clearTimeout(timer);\n }, [widthPct]);\n\n return (\n <div\n ref={ref}\n style={{\n background: isDark ? '#1a1a1e' : '#f0f0f2',\n borderRadius: 4,\n height: 5,\n overflow: 'hidden',\n flex: 1,\n minWidth: 40,\n }}\n >\n <div\n style={{\n height: '100%',\n width: `${width}%`,\n background: color,\n borderRadius: 4,\n transition: 'width 0.55s cubic-bezier(0.4, 0, 0.2, 1)',\n boxShadow: `0 0 6px ${color}88`,\n }}\n />\n </div>\n );\n}\n\n// ─── Metric cards ──────────────────────────────────────────────────────────\n\nfunction MetricCard({\n title,\n metric,\n description,\n lowerIsBetter = false,\n sparklineData,\n sparklineType = 'line',\n sparklineColor,\n weekLabels,\n onExpand,\n expandLabel,\n}: {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter?: boolean;\n sparklineData?: number[];\n sparklineType?: 'bar' | 'line';\n sparklineColor?: string;\n weekLabels?: string[];\n onExpand?: () => void;\n /** Persistent label shown in the card footer (instead of the hover-only \"expand ↗\"). */\n expandLabel?: string;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hovered, setHovered] = useState(false);\n\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : metric.value;\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const targetValue = metric.unit === 'hours' ? formatDuration(metric.target) : metric.target;\n const targetLabel = lowerIsBetter\n ? `Target: < ${targetValue} ${displayUnit}`.trim()\n : `Target: ≥ ${targetValue} ${displayUnit}`.trim();\n\n const hasSparkline = sparklineData && sparklineData.length >= 2 && weekLabels && weekLabels.length >= 2;\n const delta = hasSparkline ? buildDeltaLabel(sparklineData!, metric.unit, lowerIsBetter) : null;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n\n return (\n <Card\n style={{ cursor: onExpand ? 'pointer' : undefined }}\n onClick={onExpand}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>\n <CardLabel>{title}</CardLabel>\n {onExpand && (\n <span style={{\n fontSize: 9, fontWeight: 600, color: isDark ? '#3f3f46' : '#d4d4d8',\n opacity: hovered ? 1 : 0, transition: 'opacity 0.15s',\n letterSpacing: '0.05em', textTransform: 'uppercase', flexShrink: 0,\n }}>\n expand ↗\n </span>\n )}\n </div>\n {/* Right-aligned column: delta trend + direction hint stacked */}\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>\n {delta && (\n <span title={delta.tooltip} style={{\n fontSize: 10, fontWeight: 600, cursor: 'help',\n color: delta.good ? '#4ade80' : '#f87171',\n background: delta.good\n ? (isDark ? 'rgba(74,222,128,0.08)' : 'rgba(74,222,128,0.12)')\n : (isDark ? 'rgba(248,113,113,0.08)' : 'rgba(248,113,113,0.12)'),\n padding: '2px 8px', borderRadius: 4, whiteSpace: 'nowrap',\n }}>\n {delta.text}\n </span>\n )}\n <span style={{\n fontSize: 10, fontWeight: 600,\n color: isDark ? '#3f3f46' : '#d4d4d8',\n whiteSpace: 'nowrap',\n }}>\n {lowerIsBetter ? '↓ lower = better' : '↑ higher = better'}\n </span>\n </div>\n {/* Value row: big number + unit */}\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: isDark ? '#f4f4f5' : '#111114', lineHeight: 1 }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 14, color: isDark ? '#71717a' : '#71717a', fontWeight: 500 }}>\n {displayUnit}\n </span>\n )}\n </div>\n <RatingBadge rating={metric.rating} />\n {hasSparkline && (\n <div style={{ marginTop: 2 }}>\n <CompactSparkline\n values={sparklineData!}\n weekLabels={weekLabels!}\n color={sparklineColor ?? '#FA6400'}\n type={sparklineType}\n formatValue={formatVal}\n />\n </div>\n )}\n <CardDescription>{description}</CardDescription>\n <CardFooter>\n <span style={{ fontWeight: 600, color: isDark ? '#a1a1aa' : '#52525b' }}>\n {targetLabel}\n </span>\n {expandLabel && onExpand && (\n <span style={{\n fontSize: 10, fontWeight: 700,\n color: '#FA6400',\n letterSpacing: '0.04em',\n marginLeft: 'auto',\n }}>\n {expandLabel}\n </span>\n )}\n </CardFooter>\n </Card>\n );\n}\n\nfunction NaCard({ title, description }: { title: string; description: string }) {\n return (\n <Card>\n <CardLabel>{title}</CardLabel>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: '#52525b', lineHeight: 1 }}>N/A</span>\n </div>\n <CardDescription muted>{description}</CardDescription>\n </Card>\n );\n}\n\n// ─── Filter label ──────────────────────────────────────────────────────────\n\nfunction FilterLabel({ children }: { children: React.ReactNode }) {\n const theme = useTheme();\n return (\n <div style={{ fontSize: 11, fontWeight: 600, color: theme.palette.text.primary, marginBottom: 4, textTransform: 'uppercase', letterSpacing: '0.06em' }}>\n {children}\n </div>\n );\n}\n\n// ─── Main component ────────────────────────────────────────────────────────\n\nexport function DoraMetricsContent() {\n const { entity } = useEntity();\n const doraApi = useApi(doraMetricsApiRef);\n const muiTheme = useTheme();\n const textPrimary = muiTheme.palette.text.primary;\n const textSecondary = muiTheme.palette.text.secondary;\n\n const projectSlug = entity.metadata.annotations?.[ANNOTATION_PROJECT_SLUG] ?? '';\n const annotations = entity.metadata.annotations ?? {};\n\n // Per-repo overrides from catalog-info.yaml annotations\n const annotationEnvs = parseAnnotationJson<DoraEnvironment[]>(annotations[ANNOTATION_ENVIRONMENTS]);\n const annotationTargets = parseAnnotationJson<Partial<DoraTargets>>(annotations[ANNOTATION_TARGETS]);\n\n const environments: DoraEnvironment[] = annotationEnvs ?? doraApi.getEnvironments();\n const defaultEnv = environments[0];\n const defaultDays = doraApi.getDefaultDays();\n\n // Use environment name as the selection key (branch can be a multi-value pattern)\n const [selectedEnvName, setSelectedEnvName] = useState<string>(defaultEnv?.name ?? '');\n const [selectedDays, setSelectedDays] = useState<string>(String(defaultDays));\n\n const selectedEnv = environments.find(e => e.name === selectedEnvName) ?? defaultEnv;\n const days = parseInt(selectedDays, 10);\n\n const [metrics, setMetrics] = useState<DoraMetrics | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const [history, setHistory] = useState<DoraHistoryPoint[] | null>(null);\n const [expanded, setExpanded] = useState<ExpandedCardData | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!projectSlug) {\n setError(new Error(`Entity is missing the \"${ANNOTATION_PROJECT_SLUG}\" annotation.`));\n setLoading(false);\n return () => { cancelled = true; };\n }\n if (!selectedEnv) {\n setError(new Error('No environments configured for DORA metrics.'));\n setLoading(false);\n return () => { cancelled = true; };\n }\n\n setLoading(true);\n setError(null);\n setHistory(null);\n\n doraApi\n .getMetrics(projectSlug, selectedEnv, days, annotationTargets ?? undefined)\n .then(data => {\n if (!cancelled) { setMetrics(data); setLoading(false); }\n })\n .catch((err: Error) => {\n if (!cancelled) { setError(err); setLoading(false); }\n });\n\n doraApi\n .getHistory(projectSlug, selectedEnv, days)\n .then(data => { if (!cancelled) setHistory(data); })\n .catch(() => { /* history is optional — fail silently */ });\n\n return () => { cancelled = true; };\n // selectedEnv?.name is intentional — avoids re-render loops from object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [doraApi, projectSlug, selectedEnv?.name, days, annotationTargets]);\n\n if (loading) return <DoraLoadingOverlay />;\n\n if (error) {\n return (\n <InfoCard title=\"DORA Metrics\">\n <div style={{ padding: 24, color: '#f87171' }}>\n <span style={{ fontWeight: 600 }}>Error: </span>{error.message}\n </div>\n </InfoCard>\n );\n }\n\n if (!metrics) return null;\n\n return (\n <InfoCard title=\" \">\n <div style={{ padding: '4px 0', position: 'relative' }}>\n {/* Detailed overlay */}\n {expanded && (\n <DetailedOverlay data={expanded} days={days} onClose={() => setExpanded(null)} />\n )}\n\n {/* Title */}\n <div style={{ marginBottom: 16 }}>\n <div style={{ fontSize: 22, fontWeight: 700, color: textPrimary, letterSpacing: '-0.02em' }}>DORA Metrics</div>\n {selectedEnv && (\n <div style={{ fontSize: 12, color: textSecondary, marginTop: 5 }}>\n Showing metrics for{' '}\n <strong style={{ color: textPrimary }}>{selectedEnv.name}</strong>\n {' '}—{' '}\n <span style={{ fontFamily: 'monospace' }}>{selectedEnv.branch}</span>\n </div>\n )}\n </div>\n\n {/* Filters row — left aligned */}\n <div style={{ display: 'flex', alignItems: 'flex-end', gap: 16, flexWrap: 'wrap', marginBottom: 20 }}>\n {environments.length > 1 && (\n <div>\n <FilterLabel>Environment</FilterLabel>\n <Select value={selectedEnvName} onValueChange={setSelectedEnvName}>\n <SelectTrigger><SelectValue placeholder=\"Select environment\" /></SelectTrigger>\n <SelectContent>\n {environments.map(env => (\n <SelectItem key={env.name} value={env.name}>\n {env.name} ({env.branch})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n <div>\n <FilterLabel>Date Range</FilterLabel>\n <Select value={selectedDays} onValueChange={setSelectedDays}>\n <SelectTrigger><SelectValue placeholder=\"Select date range\" /></SelectTrigger>\n <SelectContent>\n {DATE_RANGE_OPTIONS.map(opt => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Metric cards — sparklines inline, click to expand */}\n {(() => {\n const wkLabels = history?.map(h => h.weekLabel) ?? [];\n const deployData = history?.map(h => h.deploymentCount) ?? [];\n const leadData = history?.map(h => h.leadTimeHours) ?? [];\n const cfrData = history?.map(h => h.changeFailureRate ?? 0) ?? [];\n const mttrData = history?.map(h => h.mttrHours ?? 0) ?? [];\n\n const bmMs = history?.map(h => h.bucketMidMs) ?? [];\n\n const mkExpand = (\n title: string, metric: DoraMetricValue, description: string,\n lowerIsBetter: boolean, sparklineValues: number[],\n sparklineType: 'bar' | 'line', sparklineColor: string, prs?: PrDetail[],\n prListLabel?: string,\n ) => () => setExpanded({\n title, metric, description, lowerIsBetter,\n sparklineValues, sparklineType, sparklineColor,\n weekLabels: wkLabels, bucketMidMs: bmMs, prs, prListLabel,\n });\n\n return (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>\n <MetricCard\n title=\"Deployment Frequency\"\n metric={metrics.deploymentFrequency}\n description=\"How often code is deployed to this branch\"\n sparklineData={deployData}\n sparklineType=\"bar\"\n sparklineColor=\"#FA6400\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Deployment Frequency', metrics.deploymentFrequency,\n 'How often code is deployed to this branch', false, deployData, 'bar', '#FA6400',\n metrics.deploymentFrequency.slowestPRs)}\n />\n <MetricCard\n title=\"Lead Time for Changes\"\n metric={metrics.leadTime}\n description=\"Average time from PR creation to merge\"\n lowerIsBetter\n sparklineData={leadData}\n sparklineType=\"line\"\n sparklineColor=\"#818cf8\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Lead Time for Changes', metrics.leadTime,\n 'Average time from PR creation to merge', true, leadData, 'line', '#818cf8', metrics.leadTime.slowestPRs)}\n />\n {metrics.changeFailureRate !== null ? (\n <MetricCard\n title=\"Change Failure Rate\"\n metric={metrics.changeFailureRate}\n description=\"% of all merged PRs that were hotfixes\"\n lowerIsBetter\n sparklineData={cfrData}\n sparklineType=\"line\"\n sparklineColor=\"#f87171\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Change Failure Rate', metrics.changeFailureRate,\n '% of all merged PRs that were hotfixes', true, cfrData, 'line', '#f87171')}\n />\n ) : (\n <NaCard title=\"Change Failure Rate\" description=\"Only tracked on production branches\" />\n )}\n {metrics.mttr !== null ? (\n <MetricCard\n title=\"Mean Time to Restore\"\n metric={metrics.mttr}\n description=\"Avg time from hotfix PR open to merge\"\n lowerIsBetter\n sparklineData={mttrData}\n sparklineType=\"line\"\n sparklineColor=\"#fbbf24\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Mean Time to Restore', metrics.mttr,\n 'Avg time from hotfix PR open to merge', true, mttrData, 'line', '#fbbf24', metrics.mttr.slowestPRs)}\n />\n ) : (\n <NaCard title=\"Mean Time to Restore\" description=\"Only tracked on production branches\" />\n )}\n {metrics.numberOfHotfixes !== null ? (\n <MetricCard\n title=\"Hotfixes to Production\"\n metric={metrics.numberOfHotfixes}\n description={`PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`}\n lowerIsBetter\n expandLabel={metrics.numberOfHotfixes.value > 0 ? `View ${metrics.numberOfHotfixes.value} PR${metrics.numberOfHotfixes.value !== 1 ? 's' : ''} →` : undefined}\n onExpand={mkExpand(\n 'Hotfixes to Production',\n metrics.numberOfHotfixes,\n `PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`,\n true,\n [],\n 'bar',\n '#f87171',\n metrics.numberOfHotfixes.slowestPRs,\n 'All hotfixes',\n )}\n />\n ) : (\n <NaCard title=\"Hotfixes to Production\" description=\"Only tracked on production branches\" />\n )}\n </div>\n );\n })()}\n\n </div>\n </InfoCard>\n );\n}\n"],"names":["max"],"mappings":"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"}
1
+ {"version":3,"file":"DoraMetricsContent.esm.js","sources":["../../src/components/DoraMetricsContent.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport { useTheme } from '@material-ui/core/styles';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { InfoCard } from '@backstage/core-components';\nimport { doraMetricsApiRef } from '../api/types';\nimport { niceHourTicks, niceCountTicks } from '../api/chartUtils';\nimport type { DoraEnvironment, DoraHistoryPoint, DoraMetrics, DoraMetricValue, DoraTargets, PrDetail } from '../api/types';\nimport { RatingBadge } from './ui/badge';\nimport { Card, CardLabel, CardFooter, CardDescription } from './ui/card';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from './ui/select';\nimport { ExternalLink } from 'lucide-react';\n\nconst ANNOTATION_PROJECT_SLUG = 'github.com/project-slug';\n/** Override the global environments list for this specific entity. JSON array of DoraEnvironment objects. */\nconst ANNOTATION_ENVIRONMENTS = 'dora-metrics/environments';\n/** Override the global performance targets for this specific entity. JSON object matching DoraTargets. */\nconst ANNOTATION_TARGETS = 'dora-metrics/targets';\n\n/** Parse entity annotation overrides. Returns undefined for malformed JSON to fail gracefully. */\nfunction parseAnnotationJson<T>(raw: string | undefined): T | undefined {\n if (!raw) return undefined;\n try { return JSON.parse(raw) as T; } catch { return undefined; }\n}\n\nconst DATE_RANGE_OPTIONS = [\n { value: '7', label: 'Last 7 days' },\n { value: '14', label: 'Last 14 days' },\n { value: '30', label: 'Last 30 days' },\n { value: '60', label: 'Last 60 days' },\n { value: '90', label: 'Last 90 days' },\n];\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction formatDuration(hours: number): string {\n const totalMinutes = Math.round(hours * 60);\n const d = Math.floor(totalMinutes / (24 * 60));\n const h = Math.floor((totalMinutes % (24 * 60)) / 60);\n const m = totalMinutes % 60;\n if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`;\n if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`;\n return `${m}m`;\n}\n\n// Red → Orange → Yellow → Lime → Green gradient (slowest to fastest)\nconst DURATION_GRADIENT = ['#f87171', '#fb923c', '#fbbf24', '#a3e635', '#4ade80'];\n\nfunction durationColor(index: number, total: number): string {\n if (total <= 1) return DURATION_GRADIENT[0];\n const step = (DURATION_GRADIENT.length - 1) / (total - 1);\n return DURATION_GRADIENT[Math.round(index * step)];\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\n// Period-over-period delta — compares last bucket vs second-to-last bucket\nfunction buildDeltaLabel(\n values: number[],\n unit: string,\n lowerIsBetter: boolean,\n): { text: string; tooltip: string; good: boolean } | null {\n if (values.length < 2) return null;\n const curr = values[values.length - 1];\n const prev = values[values.length - 2];\n const diff = curr - prev;\n if (Math.abs(diff) < 0.001) return null;\n const good = lowerIsBetter ? diff < 0 : diff > 0;\n const arrow = diff > 0 ? '↑' : '↓';\n\n const fmt = (v: number) =>\n unit === 'hours' ? formatDuration(v) :\n unit === '%' ? `${Math.round(v * 10) / 10}%` :\n unit === 'per week' ? `${Math.round(v * 10) / 10}/wk` :\n `${Math.round(v * 10) / 10} ${unit}`;\n\n const direction = good ? 'improving' : 'worsening';\n return {\n text: `${arrow} ${fmt(Math.abs(diff))} ${direction}`,\n tooltip: `Latest period: ${fmt(curr)} · Previous period: ${fmt(prev)}\\nEach period = one time bucket (~1/7th of your selected date range)`,\n good,\n };\n}\n\n// ─── Loading overlay ────────────────────────────────────────────────────────\n\nconst LOADING_MESSAGES = [\n 'Establishing routes…',\n 'Syncing catalog…',\n 'Loading plugins…',\n 'Fetching PR data…',\n 'Reading entity graph…',\n];\nconst STAGES = ['FETCH', 'PARSE', 'SCORE', 'RENDER'] as const;\nconst FONT_IMPACT = '\"Impact\",\"Haettenschweiler\",\"Franklin Gothic Heavy\",\"Arial Black\",sans-serif';\nconst FONT_MONO = '\"JetBrains Mono\",\"Fira Code\",\"Consolas\",monospace';\n\nfunction DoraLoadingOverlay() {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n const [activeStage, setActiveStage] = useState(0);\n const [msgKey, setMsgKey] = useState(0);\n const [msgIdx, setMsgIdx] = useState(0);\n\n useEffect(() => {\n const st = setInterval(() => setActiveStage(s => (s + 1) % STAGES.length), 800);\n return () => clearInterval(st);\n }, []);\n\n useEffect(() => {\n const mt = setInterval(() => { setMsgIdx(i => (i + 1) % LOADING_MESSAGES.length); setMsgKey(k => k + 1); }, 2200);\n return () => clearInterval(mt);\n }, []);\n\n const textShadow = isDark\n ? '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 #5A1800, 12px 12px 0 rgba(0,0,0,0.55), 0 0 60px rgba(250,100,0,0.45)'\n : '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 rgba(80,20,0,0.28), 0 0 32px rgba(250,100,0,0.22)';\n\n const mutedColor = isDark ? '#3f3f46' : '#a1a1aa';\n const subtitleColor = isDark ? '#52525b' : '#71717a';\n const borderColor = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n\n return (\n <>\n {/* Frosted glass backdrop — blurs whatever is behind */}\n <div aria-hidden style={{\n position: 'fixed', inset: 0, zIndex: 900,\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n background: isDark ? 'rgba(6,6,9,0.65)' : 'rgba(253,252,251,0.70)',\n }} />\n\n {/* Centered card */}\n <div style={{\n position: 'fixed', zIndex: 901,\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n display: 'flex', flexDirection: 'column', alignItems: 'center',\n padding: '48px 56px 40px',\n borderRadius: 20,\n background: isDark ? 'rgba(9,9,12,0.82)' : 'rgba(255,255,255,0.88)',\n border: `1px solid ${borderColor}`,\n boxShadow: isDark\n ? '0 0 0 1px rgba(250,100,0,0.06), 0 32px 80px rgba(0,0,0,0.65)'\n : '0 32px 80px rgba(0,0,0,0.12)',\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n animation: 'dlsCardIn 0.35s cubic-bezier(0.34,1.2,0.64,1) both',\n overflow: 'visible',\n }}>\n\n {/* Breathing ambient glow — inside card */}\n <div aria-hidden style={{\n position: 'absolute', width: 500, height: 360,\n left: '50%', top: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n background: `radial-gradient(ellipse at center, ${isDark ? 'rgba(250,100,0,0.08)' : 'rgba(250,100,0,0.05)'} 0%, transparent 70%)`,\n animation: 'dlsBreath 3.2s ease-in-out infinite',\n pointerEvents: 'none', borderRadius: 20,\n }} />\n\n {/* DORA wordmark */}\n <div style={{ display: 'flex', lineHeight: 1, marginBottom: 6 }}>\n {['D','O','R','A'].map((letter, i) => (\n <span key={i} style={{\n fontFamily: FONT_IMPACT, fontWeight: 900, fontSize: 110,\n color: '#FA6400', letterSpacing: '0.04em', display: 'inline-block',\n transform: 'skewX(-6deg)', textShadow,\n WebkitTextStroke: '0.5px #C24E00',\n animation: `dlsLetterDrop 0.6s cubic-bezier(0.34,1.45,0.64,1) ${i * 0.1}s both`,\n }}>\n {letter}\n </span>\n ))}\n </div>\n\n {/* Subtitle */}\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 13, fontWeight: 400,\n letterSpacing: '0.06em', color: subtitleColor, marginBottom: 32,\n animation: 'dlsFadeUp 0.4s ease 0.55s both' }}>\n Metrics\n </span>\n\n {/* Pipeline stages */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 0, marginBottom: 20, animation: 'dlsFadeUp 0.4s ease 0.7s both' }}>\n {STAGES.map((stage, i) => {\n const isActive = i === activeStage;\n const isComplete = i < activeStage;\n return (\n <div key={stage} style={{ display: 'flex', alignItems: 'center', gap: 0 }}>\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, width: 64 }}>\n <div style={{ position: 'relative', width: 12, height: 12 }}>\n {isActive && (\n <div style={{ position: 'absolute', inset: -6, borderRadius: '50%',\n border: '1.5px solid rgba(250,100,0,0.5)', animation: 'dlsPulse 1s ease-out infinite' }} />\n )}\n <div style={{\n width: 12, height: 12, borderRadius: '50%',\n background: (isActive || isComplete) ? '#FA6400' : (isDark ? '#27272a' : '#e4e4e7'),\n border: `2px solid ${(isActive || isComplete) ? '#C24E00' : (isDark ? '#3f3f46' : '#d4d4d8')}`,\n boxShadow: isActive ? '0 0 14px rgba(250,100,0,0.7)' : 'none',\n transition: 'background 0.3s, box-shadow 0.3s',\n }} />\n </div>\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 8, fontWeight: 700,\n letterSpacing: '0.12em', textTransform: 'uppercase',\n color: isActive ? '#FA6400' : isComplete ? mutedColor : mutedColor,\n transition: 'color 0.3s' }}>\n {stage}\n </span>\n </div>\n {i < STAGES.length - 1 && (\n <div style={{ width: 32, height: 2, marginBottom: 14, position: 'relative', overflow: 'hidden',\n background: isDark ? '#27272a' : '#e4e4e7', borderRadius: 2 }}>\n <div style={{\n position: 'absolute', inset: 0, borderRadius: 2, background: '#FA6400',\n transformOrigin: 'left center',\n transform: `scaleX(${i < activeStage ? 1 : isActive ? 0.5 : 0})`,\n transition: 'transform 0.4s ease',\n }} />\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Status message */}\n <span key={msgKey} style={{ fontFamily: FONT_MONO, fontSize: 11,\n color: mutedColor, letterSpacing: '0.04em', animation: 'dlsFadeUp 0.3s ease both' }}>\n {LOADING_MESSAGES[msgIdx]}\n </span>\n\n </div>{/* end card */}\n\n <style>{`\n @keyframes dlsLetterDrop {\n from { opacity: 0; transform: skewX(-6deg) translateY(-32px) scale(1.1); }\n 65% { transform: skewX(-6deg) translateY(6px) scale(0.95); }\n to { opacity: 1; transform: skewX(-6deg) translateY(0) scale(1); }\n }\n @keyframes dlsFadeUp {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes dlsBreath {\n 0%, 100% { transform: translateX(-50%) translateY(-50%) scale(0.85); opacity: 0.6; }\n 50% { transform: translateX(-50%) translateY(-50%) scale(1.2); opacity: 1; }\n }\n @keyframes dlsPulse {\n from { transform: scale(0.6); opacity: 0.9; }\n to { transform: scale(2.2); opacity: 0; }\n }\n @keyframes dlsCardIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Compact sparkline (with hover tooltip + date axis) ────────────────────\n\nfunction CompactSparkline({\n values,\n weekLabels,\n color,\n type,\n formatValue,\n height = 36,\n}: {\n values: number[];\n weekLabels: string[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n height?: number;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n\n const VW = 400; // viewBox units\n const mutedBorder = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';\n const tooltipBg = isDark ? '#1c1c20' : '#ffffff';\n const tooltipBdr = isDark ? '#3f3f46' : '#e4e4e7';\n const tooltipText = isDark ? '#ededef' : '#111114';\n const font = 'Inter,system-ui,sans-serif';\n\n const handleMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left) / rect.width;\n setHoverIdx(Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1)))));\n };\n\n if (type === 'bar') {\n const max = Math.max(...values, 1);\n const gap = 4;\n const barW = (VW - gap * (values.length - 1)) / values.length;\n\n const hoverX = hoverIdx !== null\n ? hoverIdx * (barW + gap) + barW / 2\n : null;\n const tooltipX = hoverX !== null ? Math.min(hoverX - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n {values.map((v, i) => {\n const h = Math.max(2, (v / max) * (height - 4));\n return (\n <rect key={i} x={i * (barW + gap)} y={height - h} width={barW} height={h} rx={1.5}\n fill={color} opacity={i === hoverIdx ? 1 : 0.3 + (i / values.length) * 0.55} />\n );\n })}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverIdx !== null && hoverX !== null && (\n <>\n <rect x={tooltipX} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n }\n\n if (values.length < 2) return null;\n const max = Math.max(...values, 0.01);\n const min = Math.min(...values);\n const range = max - min || max || 1;\n const pad = 3;\n const pts = values.map((v, i): [number, number] => [\n (i / (values.length - 1)) * (VW - pad * 2) + pad,\n (height - pad * 2) - ((v - min) / range) * (height - pad * 2 - 2) + pad,\n ]);\n const d = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const area = `${d} L${pts[pts.length-1][0]},${height} L${pts[0][0]},${height} Z`;\n const hoverPt = hoverIdx !== null ? pts[hoverIdx] : null;\n const tooltipX2 = hoverPt ? Math.min(hoverPt[0] - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n <path d={area} fill={color} opacity={0.07} />\n <path d={d} fill=\"none\" stroke={color} strokeWidth={1.5} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n {pts.map(([x, y], i) => (\n <circle key={i} cx={x} cy={y} r={i === hoverIdx ? 3.5 : i === pts.length - 1 ? 2.5 : 0} fill={color} />\n ))}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverPt && hoverIdx !== null && (\n <>\n <line x1={hoverPt[0]} y1={0} x2={hoverPt[0]} y2={height} stroke={color} strokeWidth={1} strokeDasharray=\"2 2\" opacity={0.4} />\n <rect x={tooltipX2} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX2 + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n}\n\n// ─── Detailed interactive chart ────────────────────────────────────────────\n\ninterface ChartTooltipState {\n x: number;\n y: number;\n primary: string;\n secondary?: string;\n}\n\nfunction DetailedChart({\n values,\n weekLabels,\n bucketMidMs,\n color,\n type,\n formatValue,\n tickUnit,\n prs,\n days,\n hoveredPrNumber,\n onPrHover,\n}: {\n values: number[];\n weekLabels: string[];\n bucketMidMs: number[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n tickUnit?: 'hours' | 'count';\n prs?: PrDetail[];\n days: number;\n hoveredPrNumber?: number | null;\n onPrHover?: (num: number | null) => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n const [tooltip, setTooltip] = useState<ChartTooltipState | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const W = 800, H = 260;\n const PAD = { top: 16, right: 16, bottom: 36, left: 56 };\n const cW = W - PAD.left - PAD.right;\n const cH = H - PAD.top - PAD.bottom;\n\n // Y scale: nice tick-aligned range so axis labels are clean intervals.\n const prMaxDuration = prs && prs.length > 0 ? Math.max(...prs.map(p => p.durationHours)) : 0;\n const rawDataMax = Math.max(...values.filter(v => v > 0), prMaxDuration, 0.01);\n const yTicks = tickUnit === 'hours'\n ? niceHourTicks(rawDataMax)\n : tickUnit === 'count'\n ? niceCountTicks(rawDataMax)\n : [0, 0.25, 0.5, 0.75, 1].map(t => t * rawDataMax);\n const dataMin = 0;\n const dataMax = yTicks[yTicks.length - 1];\n const dataRange = dataMax - dataMin || 1;\n const yScale = (v: number) => cH - ((v - dataMin) / dataRange) * cH;\n\n // Shared timestamp-based x-axis\n const cutoffMs = Date.now() - days * 24 * 60 * 60 * 1000;\n const rangeMs = days * 24 * 60 * 60 * 1000;\n const xTime = (ms: number) => Math.max(0, Math.min(cW, ((ms - cutoffMs) / rangeMs) * cW));\n\n const xIdx = (i: number) => bucketMidMs.length === values.length\n ? xTime(bucketMidMs[i])\n : (values.length > 1 ? (i / (values.length - 1)) * cW : cW / 2);\n\n const pts: [number, number][] = values.map((v, i) => [PAD.left + xIdx(i), PAD.top + yScale(v)]);\n const linePath = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const areaPath = pts.length > 1\n ? `${linePath} L${pts[pts.length-1][0]},${PAD.top+cH} L${pts[0][0]},${PAD.top+cH} Z`\n : '';\n\n const gap = 6;\n const barW = values.length > 1 ? (cW - gap * (values.length - 1)) / values.length : cW;\n\n const gridColor = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)';\n const axisColor = isDark ? '#3f3f46' : '#d4d4d8';\n const labelColor = isDark ? '#52525b' : '#a1a1aa';\n const font = 'Inter,system-ui,sans-serif';\n const gradId = `dg_${color.replace('#','')}`;\n\n // Find the nearest bucket index for a given timestamp\n const nearestBucket = (ms: number): number => {\n if (bucketMidMs.length === 0) return 0;\n let best = 0, bestDist = Infinity;\n bucketMidMs.forEach((mid, i) => {\n const d = Math.abs(ms - mid);\n if (d < bestDist) { bestDist = d; best = i; }\n });\n return best;\n };\n\n const handleSvgMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left - PAD.left * (rect.width / W)) / (rect.width * cW / W);\n const idx = Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1))));\n setHoverIdx(idx);\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y, primary: formatValue(values[idx]), secondary: weekLabels[idx] });\n };\n\n return (\n <div ref={containerRef} style={{ position: 'relative' }}>\n <svg viewBox={`0 0 ${W} ${H}`} width=\"100%\" style={{ display: 'block' }}\n onMouseMove={handleSvgMouseMove}\n onMouseLeave={() => { setHoverIdx(null); setTooltip(null); }}>\n <defs>\n <linearGradient id={gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.28} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n {/* Clip PR dots to the chart area */}\n <clipPath id={`prClip_${gradId}`}>\n <rect x={PAD.left} y={PAD.top - 8} width={cW} height={cH + 16} />\n </clipPath>\n </defs>\n\n {/* Grid + Y-axis */}\n {yTicks.map((v, i) => {\n const y = PAD.top + yScale(v);\n return (\n <g key={i}>\n {i > 0 && <line x1={PAD.left} y1={y} x2={PAD.left+cW} y2={y} stroke={gridColor} strokeWidth={1} strokeDasharray=\"3 4\" />}\n <text x={PAD.left - 6} y={y + 4} textAnchor=\"end\" fill={labelColor} fontSize={10} fontFamily={font}>\n {formatValue(v)}\n </text>\n </g>\n );\n })}\n <line x1={PAD.left} y1={PAD.top+cH} x2={PAD.left+cW} y2={PAD.top+cH} stroke={axisColor} strokeWidth={1} />\n\n {/* Chart body */}\n {type === 'bar' ? (\n values.map((v, i) => {\n const bH = Math.max(2, ((v - dataMin) / dataRange) * cH);\n const x = PAD.left + i * (barW + gap);\n return (\n <rect key={i} x={x} y={PAD.top+cH-bH} width={barW} height={bH} rx={3}\n fill={color} opacity={i === hoverIdx ? 0.95 : 0.4 + (i / Math.max(values.length - 1, 1)) * 0.45} />\n );\n })\n ) : (\n <>\n {/* When prs are provided, show scatter-only (no line/area/bucket dots).\n For CFR (no prs), keep a minimal line + non-zero bucket dots. */}\n {!prs && areaPath && <path d={areaPath} fill={`url(#${gradId})`} />}\n {!prs && <path d={linePath} fill=\"none\" stroke={color} strokeWidth={2} strokeLinejoin=\"round\" strokeLinecap=\"round\" />}\n {!prs && pts.map(([x, y], i) => values[i] > 0 && (\n <circle key={i} cx={x} cy={y}\n r={i === hoverIdx ? 5.5 : 4}\n fill={isDark ? '#0f0f12' : '#ffffff'} stroke={color}\n strokeWidth={i === hoverIdx ? 2.5 : 1.5} />\n ))}\n </>\n )}\n\n {/* PR data-point dots — x at bucket midpoint, y at actual duration (clamped to chart) */}\n {prs && type === 'line' && (\n <g clipPath={`url(#prClip_${gradId})`}>\n {prs.map((pr, dotIdx) => {\n const mergedMs = new Date(pr.mergedAt).getTime();\n const bIdx = nearestBucket(mergedMs);\n // Small deterministic jitter within the bucket to avoid overlap\n const jitter = ((pr.number * 17 + dotIdx * 11) % 13 - 6) * 5;\n const px = PAD.left + xIdx(bIdx) + jitter;\n // Clamp y: PR may be faster or slower than bucket avg; always visible\n const rawPy = PAD.top + yScale(pr.durationHours);\n const py = Math.max(PAD.top + 4, Math.min(PAD.top + cH - 4, rawPy));\n const isHov = pr.number === hoveredPrNumber;\n\n // Thin connector from dot to the bucket trend point\n const trendPt = pts[bIdx];\n\n return (\n <g key={pr.number} style={{ cursor: 'pointer' }}\n onMouseEnter={e => {\n e.stopPropagation();\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y,\n primary: `#${pr.number}: ${pr.title}`,\n secondary: `${formatValue(pr.durationHours)} · ${new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}` });\n onPrHover?.(pr.number);\n }}\n onMouseLeave={() => { setTooltip(null); onPrHover?.(null); }}>\n {/* connector removed — no bucket-average dot to connect to */}\n <circle cx={px} cy={py} r={isHov ? 11 : 7} fill={color} opacity={isHov ? 0.2 : 0.1} />\n <circle cx={px} cy={py} r={isHov ? 5.5 : 3.5}\n fill={isHov ? color : (isDark ? '#1a1a20' : '#fff')}\n stroke={color} strokeWidth={isHov ? 0 : 1.5}\n opacity={isHov ? 1 : 0.8} />\n </g>\n );\n })}\n </g>\n )}\n\n {/* Hover crosshair */}\n {hoverIdx !== null && type === 'line' && pts[hoverIdx] && (\n <>\n <line x1={pts[hoverIdx][0]} y1={PAD.top} x2={pts[hoverIdx][0]} y2={PAD.top+cH}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.3} />\n <line x1={PAD.left} y1={pts[hoverIdx][1]} x2={PAD.left+cW} y2={pts[hoverIdx][1]}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.2} />\n </>\n )}\n\n {/* X-axis labels */}\n {weekLabels.map((lbl, i) => {\n const total = weekLabels.length;\n const step = Math.max(1, Math.floor(total / 5));\n if (i !== 0 && i !== total - 1 && i % step !== 0) return null;\n const x = type === 'bar'\n ? PAD.left + i * (barW + gap) + barW / 2\n : PAD.left + xIdx(i);\n return (\n <text key={i} x={x} y={H - 8} textAnchor=\"middle\" fill={labelColor} fontSize={10} fontFamily={font}>\n {lbl}\n </text>\n );\n })}\n </svg>\n\n {/* Absolute tooltip — positioned relative to the chart container */}\n {tooltip && (() => {\n const TW = 220;\n const cW2 = containerRef.current?.offsetWidth ?? 800;\n const nearRight = tooltip.x + TW + 12 > cW2;\n return (\n <div style={{\n position: 'absolute',\n left: nearRight ? tooltip.x - TW - 8 : tooltip.x + 8,\n top: tooltip.y - 36,\n zIndex: 9999, pointerEvents: 'none',\n background: isDark ? '#18181b' : '#ffffff',\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}`,\n borderRadius: 7, padding: '7px 10px',\n boxShadow: isDark ? '0 6px 20px rgba(0,0,0,0.55)' : '0 6px 20px rgba(0,0,0,0.10)',\n width: TW,\n }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: isDark ? '#ededef' : '#111114',\n fontFamily: font, lineHeight: 1.4 }}>\n {tooltip.primary}\n </div>\n {tooltip.secondary && (\n <div style={{ fontSize: 11, color: isDark ? '#71717a' : '#a1a1aa', fontFamily: font, marginTop: 2 }}>\n {tooltip.secondary}\n </div>\n )}\n </div>\n );\n })()}\n </div>\n );\n}\n\n// ─── Detailed overlay ──────────────────────────────────────────────────────\n\ninterface ExpandedCardData {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter: boolean;\n sparklineValues: number[];\n sparklineType: 'bar' | 'line';\n sparklineColor: string;\n tickUnit?: 'hours' | 'count';\n weekLabels: string[];\n bucketMidMs: number[];\n prs?: PrDetail[];\n /** Override the section header above the PR list (default: \"All deployments\"). */\n prListLabel?: string;\n}\n\nfunction DetailedOverlay({\n data,\n days,\n onClose,\n}: {\n data: ExpandedCardData;\n days: number;\n onClose: () => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoveredPrNumber, setHoveredPrNumber] = useState<number | null>(null);\n const prRowRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n // Auto-scroll to the highlighted PR row when hover comes from the chart\n useEffect(() => {\n if (hoveredPrNumber !== null) {\n const el = prRowRefs.current.get(hoveredPrNumber);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, [hoveredPrNumber]);\n\n const { title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, tickUnit, weekLabels, bucketMidMs, prs, prListLabel } = data;\n const isDeployFreq = sparklineType === 'bar';\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : String(metric.value);\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n const borderColor = isDark ? '#27272a' : '#e4e4e7';\n const mutedColor = isDark ? '#52525b' : '#a1a1aa';\n const targetLabel = lowerIsBetter\n ? `Target: < ${metric.unit === 'hours' ? formatDuration(metric.target) : metric.target} ${displayUnit}`\n : `Target: ≥ ${metric.target} ${displayUnit}`;\n\n // Group deployment PRs by date (for the date table)\n const prsByDate = isDeployFreq && prs ? prs.reduce((acc, pr) => {\n const date = new Date(pr.mergedAt).toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });\n if (!acc[date]) acc[date] = [];\n acc[date].push(pr);\n return acc;\n }, {} as Record<string, PrDetail[]>) : {};\n const sortedDates = Object.keys(prsByDate).sort(\n (a, b) => new Date(prsByDate[b][0].mergedAt).getTime() - new Date(prsByDate[a][0].mergedAt).getTime()\n );\n\n return (\n <>\n {/* Backdrop */}\n <div onClick={onClose} style={{\n position: 'fixed', inset: 0, zIndex: 499,\n background: isDark ? 'rgba(0,0,0,0.6)' : 'rgba(0,0,0,0.3)',\n backdropFilter: 'blur(4px)',\n }} />\n\n {/* Panel */}\n <div style={{\n position: 'fixed',\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n width: 'min(92vw, 960px)',\n maxHeight: 'calc(100vh - 80px)',\n zIndex: 500,\n background: isDark ? '#09090c' : '#fafafa',\n border: `1px solid ${borderColor}`,\n borderRadius: 14,\n display: 'flex', flexDirection: 'column',\n overflow: 'hidden',\n animation: 'detailExpandIn 0.2s cubic-bezier(0.34,1.2,0.64,1)',\n boxShadow: isDark ? '0 24px 64px rgba(0,0,0,0.7)' : '0 24px 64px rgba(0,0,0,0.18)',\n }}>\n {/* Header */}\n <div style={{\n display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',\n padding: '20px 24px 16px',\n borderBottom: `1px solid ${borderColor}`,\n flexShrink: 0,\n }}>\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase', letterSpacing: '0.12em', marginBottom: 8 }}>\n {title} · {weekLabels[0]} – {weekLabels[weekLabels.length - 1]}\n </div>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>\n <span style={{ fontSize: 52, fontWeight: 700, color: theme.palette.text.primary, lineHeight: 1, letterSpacing: '-0.02em' }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 18, color: mutedColor, fontWeight: 500 }}>{displayUnit}</span>\n )}\n <RatingBadge rating={metric.rating} />\n </div>\n <div style={{ fontSize: 12, color: mutedColor, marginTop: 6 }}>\n {description} · <span style={{ fontStyle: 'italic' }}>{targetLabel}</span>\n </div>\n </div>\n <button type=\"button\" onClick={onClose} style={{\n all: 'unset', cursor: 'pointer', width: 30, height: 30,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n borderRadius: '50%', background: isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)',\n color: mutedColor, fontSize: 18, fontWeight: 300, transition: 'all 0.12s', flexShrink: 0,\n }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.1)'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'; }}>\n ✕\n </button>\n </div>\n\n {/* Body — scrollable */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 20 }}>\n\n {/* Chart */}\n {weekLabels.length >= 2 ? (\n <DetailedChart\n values={sparklineValues} weekLabels={weekLabels}\n bucketMidMs={bucketMidMs}\n color={sparklineColor} type={sparklineType}\n tickUnit={tickUnit}\n formatValue={formatVal} prs={isDeployFreq ? undefined : prs} days={days}\n hoveredPrNumber={hoveredPrNumber} onPrHover={setHoveredPrNumber}\n />\n ) : (\n <div style={{ color: mutedColor, fontSize: 13, textAlign: 'center', padding: '48px 0' }}>\n Not enough data — select a wider date range.\n </div>\n )}\n\n {/* === Deployment Frequency: PRs grouped by date === */}\n {isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 12,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {prListLabel ?? 'All deployments'} · {prs.length} PR{prs.length !== 1 ? 's' : ''}\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {sortedDates.map(date => (\n <div key={date}>\n {/* Date header */}\n <div style={{\n fontSize: 11, fontWeight: 700, color: sparklineColor,\n marginBottom: 6, display: 'flex', alignItems: 'center', gap: 8,\n }}>\n <span>{date}</span>\n <span style={{ color: mutedColor, fontWeight: 500 }}>· {prsByDate[date].length} PR{prsByDate[date].length > 1 ? 's' : ''}</span>\n </div>\n {/* PR rows */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, paddingLeft: 12,\n borderLeft: `2px solid ${sparklineColor}22` }}>\n {prsByDate[date].map(pr => (\n <div key={pr.number} style={{\n display: 'flex', flexDirection: 'column', gap: 5,\n padding: '7px 10px', borderRadius: 7,\n background: isDark ? '#0d0d10' : '#f7f7f9',\n border: `1px solid ${borderColor}`,\n transition: 'background 0.12s',\n }}>\n {/* Row 1: number + title + lead time + link */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: mutedColor, flexShrink: 0, minWidth: 36 }}>\n #{pr.number}\n </span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {formatDuration(pr.durationHours)} lead\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0 }}>\n <ExternalLink size={11} />\n </a>\n </div>\n {/* Row 2: author badge */}\n {pr.author && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>\n {pr.authorAvatar ? (\n <img src={pr.authorAvatar} alt={pr.author}\n style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}` }} />\n ) : (\n <div style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n background: isDark ? '#27272a' : '#e4e4e7',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n fontSize: 8, fontWeight: 700, color: mutedColor }}>\n {pr.author[0].toUpperCase()}\n </div>\n )}\n <a href={`https://github.com/${pr.author}`} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: 10, fontWeight: 500, color: mutedColor,\n textDecoration: 'none', letterSpacing: '0.01em' }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.color = '#FA6400'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.color = mutedColor; }}>\n @{pr.author}\n </a>\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* === Lead Time / MTTR: duration-ranked PR list with hover linking === */}\n {!isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 10,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {title.toLowerCase().includes('restore') ? 'Slowest Hotfix PRs' : 'Slowest PRs'}\n {' '}· hover a row to highlight on chart\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {prs.map((pr, i) => {\n const col = durationColor(i, prs.length);\n const maxDur = prs[0].durationHours;\n const barPct = maxDur > 0 ? (pr.durationHours / maxDur) * 100 : 0;\n const isHov = pr.number === hoveredPrNumber;\n return (\n <div key={pr.number}\n ref={(el) => {\n if (el) prRowRefs.current.set(pr.number, el);\n else prRowRefs.current.delete(pr.number);\n }}\n onMouseEnter={() => setHoveredPrNumber(pr.number)}\n onMouseLeave={() => setHoveredPrNumber(null)}\n style={{\n padding: '8px 12px', borderRadius: 8,\n background: isHov\n ? (isDark ? '#18181f' : '#f0f0ff')\n : (isDark ? '#111114' : '#f4f4f6'),\n border: `1px solid ${isHov ? `${sparklineColor}55` : borderColor}`,\n display: 'flex', flexDirection: 'column', gap: 5,\n transition: 'background 0.12s, border-color 0.12s',\n cursor: 'default',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: col, flexShrink: 0 }}>#{pr.number}</span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0, transition: 'color 0.12s' }}>\n <ExternalLink size={11} />\n </a>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <AnimatedBar widthPct={barPct} color={col} />\n <span style={{ fontSize: 11, fontWeight: 700, color: col, minWidth: 52, textAlign: 'right', flexShrink: 0 }}>\n {formatDuration(pr.durationHours)}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n </div>\n <style>{`\n @keyframes detailExpandIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Animated bar ──────────────────────────────────────────────────────────\n\nfunction AnimatedBar({ widthPct, color }: { widthPct: number; color: string }) {\n const [width, setWidth] = useState(0);\n const ref = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n useEffect(() => {\n const timer = setTimeout(() => setWidth(widthPct), 80);\n return () => clearTimeout(timer);\n }, [widthPct]);\n\n return (\n <div\n ref={ref}\n style={{\n background: isDark ? '#1a1a1e' : '#f0f0f2',\n borderRadius: 4,\n height: 5,\n overflow: 'hidden',\n flex: 1,\n minWidth: 40,\n }}\n >\n <div\n style={{\n height: '100%',\n width: `${width}%`,\n background: color,\n borderRadius: 4,\n transition: 'width 0.55s cubic-bezier(0.4, 0, 0.2, 1)',\n boxShadow: `0 0 6px ${color}88`,\n }}\n />\n </div>\n );\n}\n\n// ─── Metric cards ──────────────────────────────────────────────────────────\n\nfunction MetricCard({\n title,\n metric,\n description,\n lowerIsBetter = false,\n sparklineData,\n sparklineType = 'line',\n sparklineColor,\n weekLabels,\n onExpand,\n expandLabel,\n}: {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter?: boolean;\n sparklineData?: number[];\n sparklineType?: 'bar' | 'line';\n sparklineColor?: string;\n weekLabels?: string[];\n onExpand?: () => void;\n /** Persistent label shown in the card footer (instead of the hover-only \"expand ↗\"). */\n expandLabel?: string;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hovered, setHovered] = useState(false);\n\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : metric.value;\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const targetValue = metric.unit === 'hours' ? formatDuration(metric.target) : metric.target;\n const targetLabel = lowerIsBetter\n ? `Target: < ${targetValue} ${displayUnit}`.trim()\n : `Target: ≥ ${targetValue} ${displayUnit}`.trim();\n\n const hasSparkline = sparklineData && sparklineData.length >= 2 && weekLabels && weekLabels.length >= 2;\n const delta = hasSparkline ? buildDeltaLabel(sparklineData!, metric.unit, lowerIsBetter) : null;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n\n return (\n <Card\n style={{ cursor: onExpand ? 'pointer' : undefined }}\n onClick={onExpand}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>\n <CardLabel>{title}</CardLabel>\n {onExpand && (\n <span style={{\n fontSize: 9, fontWeight: 600, color: isDark ? '#3f3f46' : '#d4d4d8',\n opacity: hovered ? 1 : 0, transition: 'opacity 0.15s',\n letterSpacing: '0.05em', textTransform: 'uppercase', flexShrink: 0,\n }}>\n expand ↗\n </span>\n )}\n </div>\n {/* Right-aligned column: delta trend + direction hint stacked */}\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>\n {delta && (\n <span title={delta.tooltip} style={{\n fontSize: 10, fontWeight: 600, cursor: 'help',\n color: delta.good ? '#4ade80' : '#f87171',\n background: delta.good\n ? (isDark ? 'rgba(74,222,128,0.08)' : 'rgba(74,222,128,0.12)')\n : (isDark ? 'rgba(248,113,113,0.08)' : 'rgba(248,113,113,0.12)'),\n padding: '2px 8px', borderRadius: 4, whiteSpace: 'nowrap',\n }}>\n {delta.text}\n </span>\n )}\n <span style={{\n fontSize: 10, fontWeight: 600,\n color: isDark ? '#3f3f46' : '#d4d4d8',\n whiteSpace: 'nowrap',\n }}>\n {lowerIsBetter ? '↓ lower = better' : '↑ higher = better'}\n </span>\n </div>\n {/* Value row: big number + unit */}\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: isDark ? '#f4f4f5' : '#111114', lineHeight: 1 }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 14, color: isDark ? '#71717a' : '#71717a', fontWeight: 500 }}>\n {displayUnit}\n </span>\n )}\n </div>\n <RatingBadge rating={metric.rating} />\n {hasSparkline && (\n <div style={{ marginTop: 2 }}>\n <CompactSparkline\n values={sparklineData!}\n weekLabels={weekLabels!}\n color={sparklineColor ?? '#FA6400'}\n type={sparklineType}\n formatValue={formatVal}\n />\n </div>\n )}\n <CardDescription>{description}</CardDescription>\n <CardFooter>\n <span style={{ fontWeight: 600, color: isDark ? '#a1a1aa' : '#52525b' }}>\n {targetLabel}\n </span>\n {expandLabel && onExpand && (\n <span style={{\n fontSize: 10, fontWeight: 700,\n color: '#FA6400',\n letterSpacing: '0.04em',\n marginLeft: 'auto',\n }}>\n {expandLabel}\n </span>\n )}\n </CardFooter>\n </Card>\n );\n}\n\nfunction NaCard({ title, description }: { title: string; description: string }) {\n return (\n <Card>\n <CardLabel>{title}</CardLabel>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: '#52525b', lineHeight: 1 }}>N/A</span>\n </div>\n <CardDescription muted>{description}</CardDescription>\n </Card>\n );\n}\n\n// ─── Filter label ──────────────────────────────────────────────────────────\n\nfunction FilterLabel({ children }: { children: React.ReactNode }) {\n const theme = useTheme();\n return (\n <div style={{ fontSize: 11, fontWeight: 600, color: theme.palette.text.primary, marginBottom: 4, textTransform: 'uppercase', letterSpacing: '0.06em' }}>\n {children}\n </div>\n );\n}\n\n// ─── Main component ────────────────────────────────────────────────────────\n\nexport function DoraMetricsContent() {\n const { entity } = useEntity();\n const doraApi = useApi(doraMetricsApiRef);\n const muiTheme = useTheme();\n const textPrimary = muiTheme.palette.text.primary;\n const textSecondary = muiTheme.palette.text.secondary;\n\n const projectSlug = entity.metadata.annotations?.[ANNOTATION_PROJECT_SLUG] ?? '';\n const annotations = entity.metadata.annotations ?? {};\n\n // Per-repo overrides from catalog-info.yaml annotations\n const annotationEnvs = parseAnnotationJson<DoraEnvironment[]>(annotations[ANNOTATION_ENVIRONMENTS]);\n const annotationTargets = parseAnnotationJson<Partial<DoraTargets>>(annotations[ANNOTATION_TARGETS]);\n\n const environments: DoraEnvironment[] = annotationEnvs ?? doraApi.getEnvironments();\n const defaultEnv = environments[0];\n const defaultDays = doraApi.getDefaultDays();\n\n // Use environment name as the selection key (branch can be a multi-value pattern)\n const [selectedEnvName, setSelectedEnvName] = useState<string>(defaultEnv?.name ?? '');\n const [selectedDays, setSelectedDays] = useState<string>(String(defaultDays));\n\n const selectedEnv = environments.find(e => e.name === selectedEnvName) ?? defaultEnv;\n const days = parseInt(selectedDays, 10);\n\n const [metrics, setMetrics] = useState<DoraMetrics | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const [history, setHistory] = useState<DoraHistoryPoint[] | null>(null);\n const [expanded, setExpanded] = useState<ExpandedCardData | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!projectSlug) {\n setError(new Error(`Entity is missing the \"${ANNOTATION_PROJECT_SLUG}\" annotation.`));\n setLoading(false);\n return () => { cancelled = true; };\n }\n if (!selectedEnv) {\n setError(new Error('No environments configured for DORA metrics.'));\n setLoading(false);\n return () => { cancelled = true; };\n }\n\n setLoading(true);\n setError(null);\n setHistory(null);\n\n doraApi\n .getMetrics(projectSlug, selectedEnv, days, annotationTargets ?? undefined)\n .then(data => {\n if (!cancelled) { setMetrics(data); setLoading(false); }\n })\n .catch((err: Error) => {\n if (!cancelled) { setError(err); setLoading(false); }\n });\n\n doraApi\n .getHistory(projectSlug, selectedEnv, days)\n .then(data => { if (!cancelled) setHistory(data); })\n .catch(() => { /* history is optional — fail silently */ });\n\n return () => { cancelled = true; };\n // selectedEnv?.name is intentional — avoids re-render loops from object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [doraApi, projectSlug, selectedEnv?.name, days, annotationTargets]);\n\n if (loading) return <DoraLoadingOverlay />;\n\n if (error) {\n return (\n <InfoCard title=\"DORA Metrics\">\n <div style={{ padding: 24, color: '#f87171' }}>\n <span style={{ fontWeight: 600 }}>Error: </span>{error.message}\n </div>\n </InfoCard>\n );\n }\n\n if (!metrics) return null;\n\n return (\n <InfoCard title=\" \">\n <div style={{ padding: '4px 0', position: 'relative' }}>\n {/* Detailed overlay */}\n {expanded && (\n <DetailedOverlay data={expanded} days={days} onClose={() => setExpanded(null)} />\n )}\n\n {/* Title */}\n <div style={{ marginBottom: 16 }}>\n <div style={{ fontSize: 22, fontWeight: 700, color: textPrimary, letterSpacing: '-0.02em' }}>DORA Metrics</div>\n {selectedEnv && (\n <div style={{ fontSize: 12, color: textSecondary, marginTop: 5 }}>\n Showing metrics for{' '}\n <strong style={{ color: textPrimary }}>{selectedEnv.name}</strong>\n {' '}—{' '}\n <span style={{ fontFamily: 'monospace' }}>{selectedEnv.branch}</span>\n </div>\n )}\n </div>\n\n {/* Filters row — left aligned */}\n <div style={{ display: 'flex', alignItems: 'flex-end', gap: 16, flexWrap: 'wrap', marginBottom: 20 }}>\n {environments.length > 1 && (\n <div>\n <FilterLabel>Environment</FilterLabel>\n <Select value={selectedEnvName} onValueChange={setSelectedEnvName}>\n <SelectTrigger><SelectValue placeholder=\"Select environment\" /></SelectTrigger>\n <SelectContent>\n {environments.map(env => (\n <SelectItem key={env.name} value={env.name}>\n {env.name} ({env.branch})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n <div>\n <FilterLabel>Date Range</FilterLabel>\n <Select value={selectedDays} onValueChange={setSelectedDays}>\n <SelectTrigger><SelectValue placeholder=\"Select date range\" /></SelectTrigger>\n <SelectContent>\n {DATE_RANGE_OPTIONS.map(opt => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Metric cards — sparklines inline, click to expand */}\n {(() => {\n const wkLabels = history?.map(h => h.weekLabel) ?? [];\n const deployData = history?.map(h => h.deploymentCount) ?? [];\n const leadData = history?.map(h => h.leadTimeHours) ?? [];\n const cfrData = history?.map(h => h.changeFailureRate ?? 0) ?? [];\n const mttrData = history?.map(h => h.mttrHours ?? 0) ?? [];\n\n const bmMs = history?.map(h => h.bucketMidMs) ?? [];\n\n const mkExpand = (\n title: string, metric: DoraMetricValue, description: string,\n lowerIsBetter: boolean, sparklineValues: number[],\n sparklineType: 'bar' | 'line', sparklineColor: string, prs?: PrDetail[],\n prListLabel?: string, tickUnit?: 'hours' | 'count',\n ) => () => setExpanded({\n title, metric, description, lowerIsBetter,\n sparklineValues, sparklineType, sparklineColor, tickUnit,\n weekLabels: wkLabels, bucketMidMs: bmMs, prs, prListLabel,\n });\n\n // Per-bucket hotfix counts derived from hotfix PRs + bucket midpoints.\n const hotfixSparkData: number[] = bmMs.map(() => 0);\n if (bmMs.length > 0 && metrics?.numberOfHotfixes?.slowestPRs) {\n for (const pr of metrics.numberOfHotfixes.slowestPRs) {\n const t = new Date(pr.mergedAt).getTime();\n let bestIdx = 0, bestDist = Infinity;\n bmMs.forEach((mid, i) => { const d = Math.abs(t - mid); if (d < bestDist) { bestDist = d; bestIdx = i; } });\n hotfixSparkData[bestIdx]++;\n }\n }\n\n return (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>\n <MetricCard\n title=\"Deployment Frequency\"\n metric={metrics.deploymentFrequency}\n description=\"How often code is deployed to this branch\"\n sparklineData={deployData}\n sparklineType=\"bar\"\n sparklineColor=\"#FA6400\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Deployment Frequency', metrics.deploymentFrequency,\n 'How often code is deployed to this branch', false, deployData, 'bar', '#FA6400',\n metrics.deploymentFrequency.slowestPRs, undefined, 'count')}\n />\n <MetricCard\n title=\"Lead Time for Changes\"\n metric={metrics.leadTime}\n description=\"Average time from PR creation to merge\"\n lowerIsBetter\n sparklineData={leadData}\n sparklineType=\"line\"\n sparklineColor=\"#818cf8\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Lead Time for Changes', metrics.leadTime,\n 'Average time from PR creation to merge', true, leadData, 'line', '#818cf8', metrics.leadTime.slowestPRs, undefined, 'hours')}\n />\n {metrics.changeFailureRate !== null ? (\n <MetricCard\n title=\"Change Failure Rate\"\n metric={metrics.changeFailureRate}\n description=\"% of all merged PRs that were hotfixes\"\n lowerIsBetter\n sparklineData={cfrData}\n sparklineType=\"line\"\n sparklineColor=\"#f87171\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Change Failure Rate', metrics.changeFailureRate,\n '% of all merged PRs that were hotfixes', true, cfrData, 'line', '#f87171', undefined, undefined, 'count')}\n />\n ) : (\n <NaCard title=\"Change Failure Rate\" description=\"Only tracked on production branches\" />\n )}\n {metrics.mttr !== null ? (\n <MetricCard\n title=\"Mean Time to Restore\"\n metric={metrics.mttr}\n description=\"Avg time from hotfix PR open to merge\"\n lowerIsBetter\n sparklineData={mttrData}\n sparklineType=\"line\"\n sparklineColor=\"#fbbf24\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Mean Time to Restore', metrics.mttr,\n 'Avg time from hotfix PR open to merge', true, mttrData, 'line', '#fbbf24', metrics.mttr.slowestPRs, undefined, 'hours')}\n />\n ) : (\n <NaCard title=\"Mean Time to Restore\" description=\"Only tracked on production branches\" />\n )}\n {metrics.numberOfHotfixes !== null ? (\n <MetricCard\n title=\"Hotfixes to Production\"\n metric={metrics.numberOfHotfixes}\n description={`PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`}\n lowerIsBetter\n expandLabel={metrics.numberOfHotfixes.value > 0 ? `View ${metrics.numberOfHotfixes.value} PR${metrics.numberOfHotfixes.value !== 1 ? 's' : ''} →` : undefined}\n onExpand={mkExpand(\n 'Hotfixes to Production',\n metrics.numberOfHotfixes,\n `PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`,\n true,\n hotfixSparkData,\n 'bar',\n '#f87171',\n metrics.numberOfHotfixes.slowestPRs,\n 'All hotfixes',\n 'count',\n )}\n />\n ) : (\n <NaCard title=\"Hotfixes to Production\" description=\"Only tracked on production branches\" />\n )}\n </div>\n );\n })()}\n\n </div>\n </InfoCard>\n );\n}\n"],"names":["max"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,7 @@
1
1
  export { default as doraMetricsPlugin } from './alpha.js';
2
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
3
  import { OAuthApi, ConfigApi } from '@backstage/core-plugin-api';
4
- import * as react_jsx_runtime from 'react/jsx-runtime';
5
- import '@backstage/catalog-model';
6
- import 'react';
7
- import '@backstage/filter-predicates';
4
+ import React from 'react';
8
5
  import '@backstage/frontend-plugin-api';
9
6
 
10
7
  type DoraRating = 'elite' | 'high' | 'medium' | 'low';
@@ -94,7 +91,7 @@ declare class MockDoraMetricsClient implements DoraMetricsApi {
94
91
  getHistory(_projectSlug: string, env: DoraEnvironment, _days: number): Promise<DoraHistoryPoint[]>;
95
92
  }
96
93
 
97
- declare function DoraMetricsContent(): react_jsx_runtime.JSX.Element | null;
94
+ declare function DoraMetricsContent(): React.JSX.Element | null;
98
95
 
99
96
  export { DoraMetricsClient, DoraMetricsContent, MockDoraMetricsClient, doraMetricsApiRef };
100
97
  export type { DoraEnvironment, DoraMetricValue, DoraMetrics, DoraMetricsApi, DoraRating, DoraTargets, PrDetail };
package/package.json CHANGED
@@ -1,17 +1,27 @@
1
1
  {
2
2
  "name": "@c2l2c/backstage-plugin-dora-metrics",
3
- "version": "0.3.3",
3
+ "version": "0.4.1",
4
4
  "description": "A Backstage frontend plugin that displays DORA metrics (Deployment Frequency, Lead Time, Change Failure Rate, MTTR) for catalog entities via the GitHub API.",
5
- "main": "dist/index.cjs.js",
6
- "module": "dist/index.esm.js",
7
- "types": "dist/index.d.ts",
5
+ "main": "./dist/index.esm.js",
6
+ "module": "./dist/index.esm.js",
7
+ "types": "./dist/index.d.ts",
8
8
  "backstage": {
9
- "role": "frontend-plugin"
9
+ "pluginId": "dora-metrics",
10
+ "role": "frontend-plugin",
11
+ "pluginPackages": [
12
+ "@c2l2c/backstage-plugin-dora-metrics"
13
+ ]
10
14
  },
11
15
  "configSchema": "config.d.ts",
12
16
  "exports": {
13
- ".": "./src/index.ts",
14
- "./alpha": "./src/alpha.ts",
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.esm.js"
20
+ },
21
+ "./alpha": {
22
+ "types": "./dist/alpha.d.ts",
23
+ "default": "./dist/alpha.esm.js"
24
+ },
15
25
  "./package.json": "./package.json"
16
26
  },
17
27
  "publishConfig": {
@@ -38,7 +48,8 @@
38
48
  "lint": "backstage-cli package lint",
39
49
  "test": "backstage-cli package test",
40
50
  "clean": "backstage-cli package clean",
41
- "prepack": "yarn build"
51
+ "prepack": "backstage-cli package prepack",
52
+ "postpack": "backstage-cli package postpack"
42
53
  },
43
54
  "keywords": [
44
55
  "backstage",
@@ -67,7 +78,7 @@
67
78
  "@backstage/config": "^1.3.2",
68
79
  "@backstage/core-components": "^0.18.7",
69
80
  "@backstage/core-plugin-api": "^1.12.3",
70
- "@backstage/frontend-plugin-api": "^0.15.1",
81
+ "@backstage/frontend-plugin-api": "^0.16.2",
71
82
  "@backstage/plugin-catalog-react": "^2.0.0",
72
83
  "@material-ui/core": "^4.12.4",
73
84
  "@radix-ui/react-select": "^2.2.6",
@@ -85,5 +96,15 @@
85
96
  },
86
97
  "engines": {
87
98
  "node": ">=20"
99
+ },
100
+ "typesVersions": {
101
+ "*": {
102
+ "alpha": [
103
+ "dist/alpha.d.ts"
104
+ ],
105
+ "package.json": [
106
+ "package.json"
107
+ ]
108
+ }
88
109
  }
89
110
  }