@delmaredigital/payload-experiments 0.2.0-rc.6 → 0.3.0-rc.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.
Files changed (291) hide show
  1. package/README.md +129 -11
  2. package/dist/admin/PreviewLinks.d.ts +2 -1
  3. package/dist/admin/PreviewLinks.js +24 -16
  4. package/dist/admin/actions/ConfirmDialog.d.ts +7 -4
  5. package/dist/admin/actions/ConfirmDialog.js +37 -82
  6. package/dist/admin/actions/DecideDialog.d.ts +3 -1
  7. package/dist/admin/actions/DecideDialog.js +30 -13
  8. package/dist/admin/actions/MakeContentResult.d.ts +13 -2
  9. package/dist/admin/actions/MakeContentResult.js +115 -16
  10. package/dist/admin/actions/actions.model.d.ts +2 -4
  11. package/dist/admin/actions/actions.model.js +2 -3
  12. package/dist/admin/allocation.model.js +3 -5
  13. package/dist/admin/api.d.ts +10 -4
  14. package/dist/admin/api.js +11 -7
  15. package/dist/admin/copy/actions.d.ts +39 -3
  16. package/dist/admin/copy/actions.js +40 -4
  17. package/dist/admin/copy/armSelect.js +5 -5
  18. package/dist/admin/copy/arms.d.ts +1 -7
  19. package/dist/admin/copy/arms.js +1 -7
  20. package/dist/admin/copy/audience.d.ts +2 -1
  21. package/dist/admin/copy/audience.js +3 -2
  22. package/dist/admin/copy/common.d.ts +13 -6
  23. package/dist/admin/copy/common.js +14 -8
  24. package/dist/admin/copy/goals.d.ts +21 -6
  25. package/dist/admin/copy/goals.js +27 -6
  26. package/dist/admin/copy/readiness.d.ts +19 -0
  27. package/dist/admin/copy/readiness.js +19 -0
  28. package/dist/admin/copy/recommendation.d.ts +0 -3
  29. package/dist/admin/copy/recommendation.js +0 -3
  30. package/dist/admin/copy/results.d.ts +41 -2
  31. package/dist/admin/copy/results.js +42 -3
  32. package/dist/admin/copy/review.d.ts +1 -1
  33. package/dist/admin/copy/review.js +1 -1
  34. package/dist/admin/copy/setting.d.ts +2 -0
  35. package/dist/admin/copy/setting.js +2 -0
  36. package/dist/admin/copy/surface.d.ts +7 -4
  37. package/dist/admin/copy/surface.js +9 -4
  38. package/dist/admin/copy/testPage.d.ts +12 -0
  39. package/dist/admin/copy/testPage.js +12 -0
  40. package/dist/admin/format/date.d.ts +2 -0
  41. package/dist/admin/format/date.js +10 -0
  42. package/dist/admin/labels.d.ts +2 -7
  43. package/dist/admin/labels.js +2 -7
  44. package/dist/admin/previewLinks.model.d.ts +2 -2
  45. package/dist/admin/previewLinks.model.js +5 -7
  46. package/dist/admin/results/CiChart.js +11 -21
  47. package/dist/admin/results/DataQualityPanel.d.ts +4 -2
  48. package/dist/admin/results/DataQualityPanel.js +30 -17
  49. package/dist/admin/results/DataTable.d.ts +16 -0
  50. package/dist/admin/results/DataTable.js +152 -0
  51. package/dist/admin/results/StatTile.d.ts +7 -0
  52. package/dist/admin/results/StatTile.js +22 -0
  53. package/dist/admin/results/VerdictHero.d.ts +13 -0
  54. package/dist/admin/results/{VerdictCard.js → VerdictHero.js} +15 -12
  55. package/dist/admin/results/releasePages.model.d.ts +17 -0
  56. package/dist/admin/results/releasePages.model.js +10 -0
  57. package/dist/admin/results/results.css +64 -0
  58. package/dist/admin/results/results.model.d.ts +6 -2
  59. package/dist/admin/results/results.model.js +12 -5
  60. package/dist/admin/surface/ResultsRoute.d.ts +1 -1
  61. package/dist/admin/surface/ResultsRoute.js +60 -31
  62. package/dist/admin/surface/SurfaceShell.d.ts +11 -2
  63. package/dist/admin/surface/SurfaceShell.js +49 -14
  64. package/dist/admin/surface/TestsHome.d.ts +6 -1
  65. package/dist/admin/surface/TestsHome.js +183 -112
  66. package/dist/admin/surface/TestsSurface.js +56 -16
  67. package/dist/admin/surface/contracts.d.ts +1 -0
  68. package/dist/admin/surface/goals/GoalForm.js +341 -308
  69. package/dist/admin/surface/goals/GoalsList.js +123 -89
  70. package/dist/admin/surface/goals/data.d.ts +8 -2
  71. package/dist/admin/surface/goals/data.js +11 -3
  72. package/dist/admin/surface/goals/goals.css +10 -13
  73. package/dist/admin/surface/home.model.d.ts +7 -8
  74. package/dist/admin/surface/home.model.js +23 -12
  75. package/dist/admin/surface/newTest/NewTest.js +5 -5
  76. package/dist/admin/surface/pageBlock/parts.js +31 -26
  77. package/dist/admin/surface/readiness/ActionDialogs.js +43 -14
  78. package/dist/admin/surface/readiness/Banner.d.ts +3 -0
  79. package/dist/admin/surface/readiness/Banner.js +63 -36
  80. package/dist/admin/surface/readiness/SaveStatus.d.ts +1 -0
  81. package/dist/admin/surface/readiness/SaveStatus.js +6 -3
  82. package/dist/admin/surface/readiness/readiness.model.d.ts +2 -0
  83. package/dist/admin/surface/readiness/readiness.model.js +18 -9
  84. package/dist/admin/surface/readiness/useTransition.d.ts +1 -0
  85. package/dist/admin/surface/readiness/useTransition.js +2 -1
  86. package/dist/admin/surface/results/ReleasePages.d.ts +14 -0
  87. package/dist/admin/surface/results/ReleasePages.js +116 -0
  88. package/dist/admin/surface/results/ResultsBody.d.ts +15 -2
  89. package/dist/admin/surface/results/ResultsBody.js +281 -107
  90. package/dist/admin/surface/results/ResultsHeader.d.ts +10 -0
  91. package/dist/admin/surface/results/ResultsHeader.js +177 -0
  92. package/dist/admin/surface/results/recommendation.model.js +2 -6
  93. package/dist/admin/surface/results/useResults.d.ts +21 -3
  94. package/dist/admin/surface/results/useResults.js +2 -1
  95. package/dist/admin/surface/setting/parts.js +75 -88
  96. package/dist/admin/surface/setting/setting.css +3 -15
  97. package/dist/admin/surface/surface.css +62 -47
  98. package/dist/admin/surface/test/AdvancedSection.js +55 -48
  99. package/dist/admin/surface/test/GoalSection.js +39 -32
  100. package/dist/admin/surface/test/LengthSection.js +46 -34
  101. package/dist/admin/surface/test/Rail.d.ts +4 -0
  102. package/dist/admin/surface/test/Rail.js +83 -0
  103. package/dist/admin/surface/test/ReadinessBar.d.ts +5 -0
  104. package/dist/admin/surface/test/ReadinessBar.js +33 -0
  105. package/dist/admin/surface/test/Section.d.ts +1 -1
  106. package/dist/admin/surface/test/Section.js +36 -16
  107. package/dist/admin/surface/test/TargetingSection.js +168 -142
  108. package/dist/admin/surface/test/TestPage.d.ts +2 -1
  109. package/dist/admin/surface/test/TestPage.js +146 -59
  110. package/dist/admin/surface/test/VersionsSection.js +151 -120
  111. package/dist/admin/surface/test/fields.d.ts +11 -4
  112. package/dist/admin/surface/test/fields.js +84 -85
  113. package/dist/admin/surface/test/jumpToSection.d.ts +3 -0
  114. package/dist/admin/surface/test/jumpToSection.js +10 -0
  115. package/dist/admin/surface/test/pageParts.js +9 -3
  116. package/dist/admin/surface/test/testPage.css +81 -14
  117. package/dist/admin/surface/useTestDocument.d.ts +1 -0
  118. package/dist/admin/surface/useTestDocument.js +40 -9
  119. package/dist/admin/targeting/targeting.model.d.ts +1 -3
  120. package/dist/admin/targeting/targeting.model.js +3 -8
  121. package/dist/admin/theme.css +115 -36
  122. package/dist/admin/theme.d.ts +38 -0
  123. package/dist/admin/theme.js +38 -1
  124. package/dist/admin/useApi.d.ts +17 -2
  125. package/dist/admin/views/ExperimentsRootView.js +12 -2
  126. package/dist/collections/experiments/config.js +44 -1
  127. package/dist/collections/experiments/lockHook.js +16 -2
  128. package/dist/collections/identities.js +6 -1
  129. package/dist/collections/metrics.js +7 -0
  130. package/dist/collections/metricsGuards.d.ts +9 -0
  131. package/dist/collections/metricsGuards.js +33 -0
  132. package/dist/constants.d.ts +1 -0
  133. package/dist/constants.js +1 -0
  134. package/dist/contentDone.d.ts +4 -0
  135. package/dist/contentDone.js +5 -0
  136. package/dist/db/identities.d.ts +8 -7
  137. package/dist/db/identities.js +9 -6
  138. package/dist/db/metricUsage.d.ts +19 -0
  139. package/dist/db/metricUsage.js +54 -0
  140. package/dist/db/names.d.ts +5 -0
  141. package/dist/db/names.js +5 -0
  142. package/dist/db/publishedContent.d.ts +10 -0
  143. package/dist/db/publishedContent.js +43 -0
  144. package/dist/db/results.d.ts +2 -0
  145. package/dist/db/results.js +6 -2
  146. package/dist/db/snapshots.d.ts +18 -6
  147. package/dist/db/snapshots.js +23 -7
  148. package/dist/db/staleEdit.d.ts +6 -0
  149. package/dist/db/staleEdit.js +10 -0
  150. package/dist/db/sweep.js +11 -6
  151. package/dist/endpoints/events.js +3 -3
  152. package/dist/endpoints/index.js +19 -1
  153. package/dist/endpoints/recompute.js +2 -1
  154. package/dist/endpoints/results.js +5 -0
  155. package/dist/endpoints/sanitizeReadinessDetail.d.ts +1 -0
  156. package/dist/endpoints/sanitizeReadinessDetail.js +2 -0
  157. package/dist/endpoints/summary.js +20 -2
  158. package/dist/endpoints/transitions.d.ts +15 -0
  159. package/dist/endpoints/transitions.js +36 -0
  160. package/dist/errors.d.ts +8 -0
  161. package/dist/errors.js +28 -0
  162. package/dist/exports/adminClient.d.ts +1 -0
  163. package/dist/exports/adminClient.js +1 -0
  164. package/dist/exports/index.d.ts +2 -1
  165. package/dist/exports/index.js +1 -0
  166. package/dist/exports/puckEditor.d.ts +1 -0
  167. package/dist/exports/puckEditor.js +1 -0
  168. package/dist/exports/rsc.d.ts +5 -1
  169. package/dist/exports/rsc.js +2 -0
  170. package/dist/hooks/hostHook.js +3 -2
  171. package/dist/hooks/pageGuard.d.ts +5 -0
  172. package/dist/hooks/pageGuard.js +121 -0
  173. package/dist/labels/arms.d.ts +7 -0
  174. package/dist/labels/arms.js +7 -0
  175. package/dist/log.d.ts +7 -0
  176. package/dist/log.js +38 -0
  177. package/dist/manifest/compile.d.ts +5 -0
  178. package/dist/manifest/compile.js +5 -1
  179. package/dist/options.js +23 -0
  180. package/dist/plugin.js +26 -2
  181. package/dist/puck/copy.d.ts +1 -1
  182. package/dist/puck/copy.js +6 -6
  183. package/dist/puck/editor/editor.chrome.css +235 -0
  184. package/dist/puck/editor/editor.css +241 -43
  185. package/dist/results/aggregate.js +4 -3
  186. package/dist/results/analyse.d.ts +4 -1
  187. package/dist/results/analyse.js +27 -11
  188. package/dist/results/cuped.js +3 -2
  189. package/dist/results/identityCredit.d.ts +15 -7
  190. package/dist/results/identityCredit.js +32 -33
  191. package/dist/results/rolloutUnits.js +2 -1
  192. package/dist/results/snapshot.js +8 -2
  193. package/dist/results/srm.js +2 -1
  194. package/dist/results/verdict.d.ts +2 -0
  195. package/dist/results/verdict.js +18 -1
  196. package/dist/sanitizeReadinessDetail.d.ts +7 -0
  197. package/dist/sanitizeReadinessDetail.js +54 -0
  198. package/dist/server/linkIdentity.d.ts +10 -1
  199. package/dist/server/linkIdentity.js +20 -18
  200. package/dist/server/metadata.d.ts +5 -0
  201. package/dist/server/metadata.js +9 -1
  202. package/dist/server/recordContentChange.js +2 -1
  203. package/dist/server/recordExposures.js +3 -3
  204. package/dist/server/runResults.d.ts +3 -2
  205. package/dist/server/runResults.js +125 -34
  206. package/dist/server/trackConversion.js +5 -6
  207. package/dist/targeting/values.d.ts +4 -0
  208. package/dist/targeting/values.js +10 -0
  209. package/dist/transitions/addMetric.js +8 -0
  210. package/dist/transitions/archive.js +2 -3
  211. package/dist/transitions/checkStart.d.ts +6 -3
  212. package/dist/transitions/checkStart.js +15 -0
  213. package/dist/transitions/contentFields.d.ts +7 -0
  214. package/dist/transitions/contentFields.js +20 -0
  215. package/dist/transitions/decide.js +6 -1
  216. package/dist/transitions/deleteExperiment.js +2 -1
  217. package/dist/transitions/dismissContentEntry.d.ts +8 -0
  218. package/dist/transitions/dismissContentEntry.js +45 -0
  219. package/dist/transitions/makeContent.d.ts +5 -2
  220. package/dist/transitions/makeContent.js +217 -118
  221. package/dist/transitions/phaseRecord.d.ts +8 -2
  222. package/dist/transitions/placements.d.ts +1 -0
  223. package/dist/transitions/placements.js +4 -0
  224. package/dist/transitions/preflightData.d.ts +1 -1
  225. package/dist/transitions/preflightData.js +42 -4
  226. package/dist/transitions/releasePages.d.ts +8 -0
  227. package/dist/transitions/releasePages.js +26 -0
  228. package/dist/transitions/restoreContentEntry.d.ts +8 -0
  229. package/dist/transitions/restoreContentEntry.js +47 -0
  230. package/dist/transitions/start.js +30 -5
  231. package/dist/types/contracts.d.ts +14 -0
  232. package/dist/types/endpoints.d.ts +34 -3
  233. package/dist/types/index.d.ts +1 -0
  234. package/dist/types/index.js +1 -0
  235. package/dist/types/reasons.d.ts +3 -0
  236. package/dist/types/reasons.js +1 -0
  237. package/dist/types/snapshot.d.ts +6 -1
  238. package/dist/ui/Banner.d.ts +2 -0
  239. package/dist/ui/Banner.js +2 -0
  240. package/dist/ui/Breadcrumb.d.ts +7 -0
  241. package/dist/ui/Breadcrumb.js +25 -0
  242. package/dist/ui/Button.d.ts +15 -0
  243. package/dist/ui/Button.js +32 -0
  244. package/dist/ui/Card.d.ts +12 -0
  245. package/dist/ui/Card.js +40 -0
  246. package/dist/ui/Checkbox.d.ts +2 -0
  247. package/dist/ui/Checkbox.js +2 -0
  248. package/dist/{admin/components → ui}/ChipsInput.d.ts +4 -3
  249. package/dist/{admin/components → ui}/ChipsInput.js +20 -12
  250. package/dist/ui/Dialog.d.ts +13 -0
  251. package/dist/ui/Dialog.js +85 -0
  252. package/dist/ui/EmptyState.d.ts +2 -0
  253. package/dist/ui/EmptyState.js +2 -0
  254. package/dist/ui/Feedback.d.ts +24 -0
  255. package/dist/ui/Feedback.js +40 -0
  256. package/dist/ui/Inputs.d.ts +34 -0
  257. package/dist/ui/Inputs.js +225 -0
  258. package/dist/ui/NumberInput.d.ts +2 -0
  259. package/dist/ui/NumberInput.js +2 -0
  260. package/dist/ui/Range.d.ts +2 -0
  261. package/dist/ui/Range.js +2 -0
  262. package/dist/ui/SearchInput.d.ts +2 -0
  263. package/dist/ui/SearchInput.js +2 -0
  264. package/dist/ui/SectionCard.d.ts +2 -0
  265. package/dist/ui/SectionCard.js +2 -0
  266. package/dist/ui/Select.d.ts +2 -0
  267. package/dist/ui/Select.js +2 -0
  268. package/dist/ui/StatusChip.d.ts +2 -0
  269. package/dist/ui/StatusChip.js +2 -0
  270. package/dist/ui/Tabs.d.ts +14 -0
  271. package/dist/ui/Tabs.js +54 -0
  272. package/dist/ui/TextInput.d.ts +2 -0
  273. package/dist/ui/TextInput.js +2 -0
  274. package/dist/ui/Textarea.d.ts +2 -0
  275. package/dist/ui/Textarea.js +2 -0
  276. package/dist/ui/Toggle.d.ts +2 -0
  277. package/dist/ui/Toggle.js +2 -0
  278. package/dist/ui/accent.d.ts +21 -0
  279. package/dist/ui/accent.js +81 -0
  280. package/dist/ui/index.d.ts +9 -0
  281. package/dist/ui/index.js +9 -0
  282. package/dist/ui/ui.css +92 -0
  283. package/package.json +1 -1
  284. package/dist/admin/components/chipsInput.css +0 -11
  285. package/dist/admin/results/ArmTable.d.ts +0 -8
  286. package/dist/admin/results/ArmTable.js +0 -113
  287. package/dist/admin/results/VerdictCard.d.ts +0 -9
  288. package/dist/admin/surface/goals/GoalsBreadcrumb.d.ts +0 -5
  289. package/dist/admin/surface/goals/GoalsBreadcrumb.js +0 -47
  290. package/dist/admin/surface/test/TestHeader.d.ts +0 -4
  291. package/dist/admin/surface/test/TestHeader.js +0 -69
@@ -1,10 +1,11 @@
1
- /** Preview URLs identify pages; counts use the most placements in any one version. */ export function previewPages(placements) {
1
+ /** Preview URLs identify pages; counts use the most placements in any one version. */ export function previewPages(placements, flagPoint) {
2
2
  const pages = new Map();
3
- for (const placement of placements){
4
- const key = `${placement.collection}\u0000${String(placement.id)}`;
3
+ for (const [index, placement] of placements.entries()){
4
+ const key = `${placement.collection}\u0000${String(placement.id)}${placement.collection === flagPoint ? `\u0000${index}` : ''}`;
5
5
  const existing = pages.get(key);
6
6
  if (existing) {
7
7
  const { page, versions } = existing;
8
+ if (!page.editorUrl && placement.editorUrl) page.editorUrl = placement.editorUrl;
8
9
  const count = (versions.get(placement.detail) ?? 0) + 1;
9
10
  versions.set(placement.detail, count);
10
11
  page.slotCount = Math.max(page.slotCount, count);
@@ -12,11 +13,8 @@
12
13
  } else {
13
14
  pages.set(key, {
14
15
  page: {
16
+ ...placement,
15
17
  key,
16
- collection: placement.collection,
17
- id: placement.id,
18
- title: placement.title,
19
- url: placement.url,
20
18
  slotCount: 1
21
19
  },
22
20
  versions: new Map([
@@ -3,16 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { theme } from '../theme.js';
4
4
  import { RESULTS_COPY as C, chartSummary, contentChangeTitle } from '../copy/results.js';
5
5
  import { chartModel } from './chart.model.js';
6
+ import { formatDate } from '../format/date.js';
6
7
  import { formatPercent } from './format.js';
7
- const colors = [
8
- theme.color.textStrong,
9
- theme.color.textMuted,
10
- theme.color.borderAccent
11
- ];
12
- const date = (t)=>new Intl.DateTimeFormat('en-US', {
13
- dateStyle: 'medium',
14
- timeZone: 'UTC'
15
- }).format(t);
8
+ import { seriesColor } from './DataTable.js';
16
9
  export function CiChart({ series, metricId, metricName, phase, contentChanges }) {
17
10
  const model = chartModel({
18
11
  series,
@@ -32,9 +25,6 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
32
25
  color: theme.color.text
33
26
  },
34
27
  children: [
35
- /*#__PURE__*/ _jsx("h2", {
36
- children: C.chart
37
- }),
38
28
  /*#__PURE__*/ _jsxs("svg", {
39
29
  viewBox: "0 0 760 280",
40
30
  style: {
@@ -42,8 +32,8 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
42
32
  height: 'auto'
43
33
  },
44
34
  role: "img",
45
- "aria-label": chartSummary(metricName, model.variants.map((variant)=>variant.label).join(', '), date(from), date(to), [
46
- ...new Set(model.markers.map((marker)=>date(marker.t)))
35
+ "aria-label": chartSummary(metricName, model.variants.map((variant)=>variant.label).join(', '), formatDate(from), formatDate(to), [
36
+ ...new Set(model.markers.map((marker)=>formatDate(marker.t)))
47
37
  ]),
48
38
  children: [
49
39
  /*#__PURE__*/ _jsx("line", {
@@ -70,7 +60,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
70
60
  y: 260,
71
61
  fill: "currentColor",
72
62
  fontSize: 12,
73
- children: date(from)
63
+ children: formatDate(from)
74
64
  }),
75
65
  /*#__PURE__*/ _jsx("text", {
76
66
  x: 680,
@@ -78,9 +68,9 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
78
68
  textAnchor: "end",
79
69
  fill: "currentColor",
80
70
  fontSize: 12,
81
- children: date(to)
71
+ children: formatDate(to)
82
72
  }),
83
- model.variants.map((variant, index)=>{
73
+ model.variants.map((variant)=>{
84
74
  const path = (points)=>{
85
75
  let connected = false;
86
76
  return points.map((point)=>{
@@ -93,7 +83,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
93
83
  return `${command}${x(point.t)},${y(point.value)}`;
94
84
  }).join(' ');
95
85
  };
96
- const color = colors[index % colors.length];
86
+ const color = seriesColor(variant.arm);
97
87
  const upper = variant.points.map((point)=>`${x(point.t)},${y(point.hi ?? high)}`);
98
88
  const lower = [
99
89
  ...variant.points
@@ -140,7 +130,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
140
130
  model.markers.map((marker, index)=>/*#__PURE__*/ _jsxs("g", {
141
131
  children: [
142
132
  /*#__PURE__*/ _jsx("title", {
143
- children: contentChangeTitle(date(marker.t))
133
+ children: contentChangeTitle(formatDate(marker.t))
144
134
  }),
145
135
  /*#__PURE__*/ _jsx("line", {
146
136
  x1: x(marker.t),
@@ -155,7 +145,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
155
145
  ]
156
146
  }),
157
147
  /*#__PURE__*/ _jsx("ul", {
158
- children: model.variants.map((variant, index)=>/*#__PURE__*/ _jsxs("li", {
148
+ children: model.variants.map((variant)=>/*#__PURE__*/ _jsxs("li", {
159
149
  style: {
160
150
  color: theme.color.text
161
151
  },
@@ -167,7 +157,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
167
157
  width: '1em',
168
158
  height: '0.5em',
169
159
  marginRight: '0.5em',
170
- backgroundColor: colors[index % colors.length]
160
+ backgroundColor: seriesColor(variant.arm)
171
161
  }
172
162
  }),
173
163
  variant.label
@@ -1,4 +1,6 @@
1
1
  import type { DataQualityItem } from './results.model.js';
2
- export declare function DataQualityPanel({ items }: {
2
+ import './results.css';
3
+ export declare function DataQualityPanel({ items, problem }: {
3
4
  items: DataQualityItem[];
4
- }): import("react").JSX.Element | null;
5
+ problem?: boolean;
6
+ }): import("react").JSX.Element;
@@ -1,28 +1,37 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { theme } from '../theme.js';
4
- import { RESULTS_COPY } from '../copy/results.js';
5
- export function DataQualityPanel({ items }) {
6
- if (items.length === 0) return null;
7
- return /*#__PURE__*/ _jsxs("section", {
8
- className: "xp-data-quality",
9
- "aria-label": RESULTS_COPY.quality,
10
- style: {
11
- color: theme.color.text,
12
- background: theme.color.surface,
13
- padding: '1rem'
14
- },
3
+ import { RESULTS_COPY as C } from '../copy/results.js';
4
+ import './results.css';
5
+ const quality = (item)=>item.id === 'srm' || item.id.startsWith('version-page-unavailable') ? 'problem' : 'watch';
6
+ export function DataQualityPanel({ items, problem = false }) {
7
+ const overall = problem || items.some((item)=>quality(item) === 'problem') ? 'problem' : items.length ? 'watch' : 'ok';
8
+ return /*#__PURE__*/ _jsxs("details", {
9
+ className: "xp-results-panel xp-data-quality",
10
+ open: overall !== 'ok',
15
11
  children: [
16
- /*#__PURE__*/ _jsx("h2", {
17
- children: RESULTS_COPY.quality
12
+ /*#__PURE__*/ _jsxs("summary", {
13
+ children: [
14
+ C.quality,
15
+ /*#__PURE__*/ _jsx("span", {
16
+ className: `xp-quality-chip xp-quality-chip--${overall}`,
17
+ children: C.qualityStates[overall]
18
+ })
19
+ ]
18
20
  }),
19
- /*#__PURE__*/ _jsx("ul", {
20
- children: items.map((item)=>/*#__PURE__*/ _jsxs("li", {
21
+ /*#__PURE__*/ _jsx("section", {
22
+ "aria-label": C.quality,
23
+ children: items.length ? items.map((item)=>/*#__PURE__*/ _jsxs("div", {
24
+ className: "xp-quality-row",
21
25
  children: [
26
+ /*#__PURE__*/ _jsx("span", {
27
+ className: `xp-quality-chip xp-quality-chip--${quality(item)}`,
28
+ children: C.qualityStates[quality(item)]
29
+ }),
22
30
  /*#__PURE__*/ _jsx("p", {
23
31
  children: item.message
24
32
  }),
25
33
  item.detail ? /*#__PURE__*/ _jsx("p", {
34
+ className: "xp-quality-detail",
26
35
  children: item.detail
27
36
  }) : null,
28
37
  item.shares ? /*#__PURE__*/ _jsx("ul", {
@@ -31,10 +40,14 @@ export function DataQualityPanel({ items }) {
31
40
  }, index))
32
41
  }) : null,
33
42
  /*#__PURE__*/ _jsx("p", {
43
+ className: "xp-quality-next",
34
44
  children: item.nextStep
35
45
  })
36
46
  ]
37
- }, item.id))
47
+ }, item.id)) : /*#__PURE__*/ _jsx("p", {
48
+ className: "xp-quality-row",
49
+ children: C.qualityOK
50
+ })
38
51
  })
39
52
  ]
40
53
  });
@@ -0,0 +1,16 @@
1
+ import type { ArmRow } from './results.model.js';
2
+ export interface DataTableProps {
3
+ rows: ArmRow[];
4
+ caption: string;
5
+ method: 'sequential' | 'bayesian';
6
+ metricKind: 'binomial' | 'count' | 'revenue';
7
+ }
8
+ import './results.css';
9
+ export declare const seriesColor: (key: string) => "var(--xp-series-a)" | "var(--xp-series-b)" | "var(--xp-series-muted)" | "var(--xp-series-c)";
10
+ export declare function Swatch({ arm }: {
11
+ arm: string;
12
+ }): import("react").JSX.Element;
13
+ export declare function DataTable({ rows, caption, metricKind, leader, primary }: DataTableProps & {
14
+ leader?: string | null;
15
+ primary?: boolean;
16
+ }): import("react").JSX.Element;
@@ -0,0 +1,152 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from 'react';
4
+ import { RESULTS_COPY as C } from '../copy/results.js';
5
+ import { CappedCell } from './CappedCell.js';
6
+ import './results.css';
7
+ export const seriesColor = (key)=>key === 'variantA' ? 'var(--xp-series-a)' : key === 'variantB' ? 'var(--xp-series-b)' : key === 'variantC' ? 'var(--xp-series-c)' : 'var(--xp-series-muted)';
8
+ export function Swatch({ arm }) {
9
+ return /*#__PURE__*/ _jsx("span", {
10
+ className: "xp-results-swatch",
11
+ style: {
12
+ background: seriesColor(arm)
13
+ },
14
+ "aria-hidden": "true"
15
+ });
16
+ }
17
+ function updateScrollCues(wrap) {
18
+ wrap.parentElement?.classList.toggle('has-left', wrap.scrollLeft > 0);
19
+ wrap.parentElement?.classList.toggle('has-right', wrap.scrollLeft + wrap.clientWidth < wrap.scrollWidth - 1);
20
+ }
21
+ export function DataTable({ rows, caption, metricKind, leader, primary = false }) {
22
+ const scrollRef = useRef(null);
23
+ useEffect(()=>{
24
+ const wrap = scrollRef.current;
25
+ if (!wrap) return;
26
+ const update = ()=>updateScrollCues(wrap);
27
+ update();
28
+ const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(update);
29
+ observer?.observe(wrap);
30
+ if (wrap.firstElementChild) observer?.observe(wrap.firstElementChild);
31
+ window.addEventListener('resize', update);
32
+ return ()=>{
33
+ observer?.disconnect();
34
+ window.removeEventListener('resize', update);
35
+ };
36
+ }, [
37
+ rows
38
+ ]);
39
+ return /*#__PURE__*/ _jsx("div", {
40
+ className: "xp-data-table-frame",
41
+ children: /*#__PURE__*/ _jsx("div", {
42
+ ref: scrollRef,
43
+ className: "xp-data-table-wrap",
44
+ tabIndex: 0,
45
+ role: "region",
46
+ "aria-label": caption,
47
+ onScroll: (event)=>updateScrollCues(event.currentTarget),
48
+ children: /*#__PURE__*/ _jsxs("table", {
49
+ className: "xp-data-table",
50
+ children: [
51
+ /*#__PURE__*/ _jsx("caption", {
52
+ children: caption
53
+ }),
54
+ /*#__PURE__*/ _jsx("thead", {
55
+ children: /*#__PURE__*/ _jsxs("tr", {
56
+ children: [
57
+ /*#__PURE__*/ _jsx("th", {
58
+ scope: "col",
59
+ children: C.group
60
+ }),
61
+ /*#__PURE__*/ _jsx("th", {
62
+ scope: "col",
63
+ className: "num",
64
+ children: C.people
65
+ }),
66
+ primary && metricKind === 'binomial' ? /*#__PURE__*/ _jsx("th", {
67
+ scope: "col",
68
+ className: "num",
69
+ children: C.conversions
70
+ }) : null,
71
+ /*#__PURE__*/ _jsx("th", {
72
+ scope: "col",
73
+ className: "num",
74
+ children: metricKind === 'binomial' ? C.rate : C.average
75
+ }),
76
+ /*#__PURE__*/ _jsx("th", {
77
+ scope: "col",
78
+ className: "num",
79
+ children: C.lift
80
+ }),
81
+ /*#__PURE__*/ _jsx("th", {
82
+ scope: "col",
83
+ className: "num",
84
+ children: C.ci
85
+ }),
86
+ primary ? /*#__PURE__*/ _jsx("th", {
87
+ scope: "col",
88
+ className: "num",
89
+ children: C.chanceToWin
90
+ }) : null
91
+ ]
92
+ })
93
+ }),
94
+ /*#__PURE__*/ _jsx("tbody", {
95
+ children: rows.map((row)=>/*#__PURE__*/ _jsxs("tr", {
96
+ className: primary && leader && row.key === leader ? 'is-lead' : undefined,
97
+ children: [
98
+ /*#__PURE__*/ _jsxs("th", {
99
+ scope: "row",
100
+ children: [
101
+ /*#__PURE__*/ _jsxs("span", {
102
+ className: "xp-results-group",
103
+ children: [
104
+ /*#__PURE__*/ _jsx(Swatch, {
105
+ arm: row.key
106
+ }),
107
+ row.label
108
+ ]
109
+ }),
110
+ row.key === 'holdout' && row.baseline ? /*#__PURE__*/ _jsx("div", {
111
+ className: "muted",
112
+ children: row.baseline
113
+ }) : null
114
+ ]
115
+ }),
116
+ /*#__PURE__*/ _jsx("td", {
117
+ className: "num",
118
+ children: row.n
119
+ }),
120
+ primary && metricKind === 'binomial' ? /*#__PURE__*/ _jsx("td", {
121
+ className: "num",
122
+ children: row.value
123
+ }) : null,
124
+ /*#__PURE__*/ _jsx("td", {
125
+ className: "num",
126
+ children: metricKind === 'revenue' ? /*#__PURE__*/ _jsx(CappedCell, {
127
+ model: {
128
+ ...row.capped,
129
+ notice: undefined
130
+ }
131
+ }) : row.rate ?? row.capped.statistic
132
+ }),
133
+ /*#__PURE__*/ _jsx("td", {
134
+ className: `num${row.baseline ? ' muted' : ''}`,
135
+ children: row.baseline ? '—' : row.lift ?? '—'
136
+ }),
137
+ /*#__PURE__*/ _jsx("td", {
138
+ className: `num${row.baseline ? ' muted' : ''}`,
139
+ children: row.baseline ? '—' : row.comparison?.method === 'sequential' ? row.comparison.adjustedCI ?? row.comparison.ci : row.comparison?.ci ?? '—'
140
+ }),
141
+ primary ? /*#__PURE__*/ _jsx("td", {
142
+ className: "num",
143
+ children: row.baseline ? '—' : row.chanceToWin ?? '—'
144
+ }) : null
145
+ ]
146
+ }, row.key))
147
+ })
148
+ ]
149
+ })
150
+ })
151
+ });
152
+ }
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ import './results.css';
3
+ export declare function StatTile({ label, value, detail }: {
4
+ label: string;
5
+ value: ReactNode;
6
+ detail?: ReactNode;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import './results.css';
4
+ export function StatTile({ label, value, detail }) {
5
+ return /*#__PURE__*/ _jsxs("div", {
6
+ className: "xp-stat-tile",
7
+ children: [
8
+ /*#__PURE__*/ _jsx("div", {
9
+ className: "xp-stat-tile-label",
10
+ children: label
11
+ }),
12
+ /*#__PURE__*/ _jsx("div", {
13
+ className: "xp-stat-tile-value",
14
+ children: value
15
+ }),
16
+ detail ? /*#__PURE__*/ _jsx("div", {
17
+ className: "xp-stat-tile-detail",
18
+ children: detail
19
+ }) : null
20
+ ]
21
+ });
22
+ }
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { VerdictCardModel, guardrailChips } from './results.model.js';
3
+ export interface VerdictHeroProps {
4
+ model: VerdictCardModel;
5
+ guardrails?: ReturnType<typeof guardrailChips>;
6
+ power?: string | null;
7
+ collecting?: string | null;
8
+ sinceShipping?: string | null;
9
+ meta?: ReactNode;
10
+ recommendation?: string;
11
+ }
12
+ import './results.css';
13
+ export declare function VerdictHero({ model, guardrails, power, collecting, sinceShipping, meta, recommendation }: VerdictHeroProps): import("react").JSX.Element;
@@ -1,14 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { theme } from '../theme.js';
4
- export function VerdictCard({ model, guardrails = [], power, collecting, sinceShipping }) {
3
+ import './results.css';
4
+ export function VerdictHero({ model, guardrails = [], power, collecting, sinceShipping, meta, recommendation }) {
5
5
  return /*#__PURE__*/ _jsxs("section", {
6
- className: "xp-verdict-card",
7
- style: {
8
- color: theme.color.text,
9
- background: theme.color.surface,
10
- padding: '1rem'
11
- },
6
+ className: "xp-verdict-hero",
12
7
  children: [
13
8
  sinceShipping ? /*#__PURE__*/ _jsx("p", {
14
9
  className: "xp-since-shipping",
@@ -30,10 +25,14 @@ export function VerdictCard({ model, guardrails = [], power, collecting, sinceSh
30
25
  className: "xp-collecting",
31
26
  children: collecting
32
27
  }) : null,
33
- guardrails.length > 0 ? /*#__PURE__*/ _jsx("ul", {
34
- className: "xp-guardrails",
28
+ recommendation ? /*#__PURE__*/ _jsx("p", {
29
+ className: "xp-recommendation",
30
+ children: recommendation
31
+ }) : null,
32
+ guardrails.length ? /*#__PURE__*/ _jsx("ul", {
33
+ className: "xp-results-chips",
35
34
  children: guardrails.map((item, index)=>/*#__PURE__*/ _jsxs("li", {
36
- className: "xp-chip",
35
+ className: "xp-tests-kind",
37
36
  children: [
38
37
  item.name,
39
38
  ": ",
@@ -44,7 +43,11 @@ export function VerdictCard({ model, guardrails = [], power, collecting, sinceSh
44
43
  !('title' in model) && power ? /*#__PURE__*/ _jsx("p", {
45
44
  className: "xp-power",
46
45
  children: power
47
- }) : null
46
+ }) : null,
47
+ /*#__PURE__*/ _jsx("div", {
48
+ className: "xp-verdict-meta",
49
+ children: meta
50
+ })
48
51
  ]
49
52
  });
50
53
  }
@@ -0,0 +1,17 @@
1
+ import type { DocId } from '../../types/contracts.js';
2
+ export interface PageReleaseDecision {
3
+ winnerArm?: string | null;
4
+ discardedAt?: string | null;
5
+ pagesReleasedAt?: string | null;
6
+ pagesReleasedBy?: string | null;
7
+ }
8
+ /** Mirrors the release-pages transition's gate; permission is checked by the caller. */
9
+ export declare function canReleasePages(doc: {
10
+ kind?: string;
11
+ status: string;
12
+ decision?: PageReleaseDecision | null;
13
+ }): boolean;
14
+ export declare function pagesReleasedBy(by: string | null | undefined, currentUserId?: DocId | null, author?: {
15
+ name?: string | null;
16
+ email?: string | null;
17
+ } | null): string | undefined;
@@ -0,0 +1,10 @@
1
+ import { RESULTS_COPY } from '../copy/results.js';
2
+ /** Mirrors the release-pages transition's gate; permission is checked by the caller. */ export function canReleasePages(doc) {
3
+ const decision = doc.decision;
4
+ return doc.kind === 'page' && doc.status === 'archived' && Boolean(decision?.winnerArm) && !decision?.discardedAt && !decision?.pagesReleasedAt;
5
+ }
6
+ export function pagesReleasedBy(by, currentUserId, author) {
7
+ if (by == null) return undefined;
8
+ if (currentUserId != null && by === String(currentUserId)) return RESULTS_COPY.you;
9
+ return author?.name ?? author?.email ?? undefined;
10
+ }
@@ -0,0 +1,64 @@
1
+ .xp-results { max-width: 1120px; display: grid; gap: var(--xp-space-8); min-width: 0; }
2
+ .xp-results h2, .xp-results h3, .xp-results p { margin: 0; }
3
+ .xp-verdict-hero { background: var(--xp-surface); border: 1px solid var(--xp-border); border-radius: var(--xp-radius-card); padding: 28px; min-width: 0; }
4
+ .xp-verdict-hero h2 { font: var(--xp-text-display); letter-spacing: -0.01em; max-width: 36ch; }
5
+ .xp-verdict-hero p { margin-top: var(--xp-space-2); color: var(--xp-text-2); }
6
+ .xp-verdict-meta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--xp-space-3); margin-top: var(--xp-space-5); padding-top: var(--xp-space-4); border-top: 1px solid var(--xp-border); color: var(--xp-text-3); font: var(--xp-text-small); }
7
+ .xp-round-meta { display: flex; align-items: center; flex-wrap: wrap; gap: var(--xp-space-2); min-width: 0; }
8
+ .xp-round-meta .xp-ui-field { display: flex; align-items: center; gap: var(--xp-space-2); margin: 0; min-width: 0; }
9
+ .xp-round-meta select { width: auto; max-width: 100%; }
10
+ .xp-results-chips { display: flex; flex-wrap: wrap; gap: var(--xp-space-2); list-style: none; padding: 0; margin-bottom: 0; }
11
+ .xp-stat-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--xp-border); border-radius: var(--xp-radius-card); background: var(--xp-surface); overflow: hidden; }
12
+ .xp-stat-tile { padding: 20px; min-width: 0; }
13
+ .xp-stat-tile + .xp-stat-tile { border-left: 1px solid var(--xp-border); }
14
+ .xp-stat-tile-label, .xp-stat-tile-detail { font: var(--xp-text-small); color: var(--xp-text-2); }
15
+ .xp-stat-tile-value { margin-top: 6px; font: 600 32px/36px var(--xp-font); font-variant-numeric: tabular-nums; }
16
+ .xp-stat-tile-detail { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
17
+ .xp-results-block { min-width: 0; }
18
+ .xp-results-block-head { display: flex; align-items: baseline; flex-wrap: wrap; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
19
+ .xp-results-block-head h2 { font: var(--xp-text-title); }
20
+ .xp-results-block-meta { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 8px; color: var(--xp-text-2); }
21
+ .xp-data-table-frame { position: relative; min-width: 0; border-radius: var(--xp-radius-card); }
22
+ .xp-data-table-wrap { overflow-x: auto; overflow-y: auto; max-height: 70vh; border: 1px solid var(--xp-border); border-radius: var(--xp-radius-card); background: var(--xp-surface); }
23
+ .xp-data-table-wrap:focus-visible { outline: 2px solid var(--xp-focus); outline-offset: 2px; }
24
+ /* Overlays stay visible above opaque sticky headers and the highlighted row. */
25
+ .xp-data-table-frame::before, .xp-data-table-frame::after { content: ''; position: absolute; top: 1px; bottom: 1px; width: var(--xp-space-6); z-index: 3; pointer-events: none; opacity: 0; }
26
+ .xp-data-table-frame::before { left: 1px; border-radius: var(--xp-radius-card) 0 0 var(--xp-radius-card); background: linear-gradient(to right, var(--xp-border-strong), transparent); }
27
+ .xp-data-table-frame::after { right: 1px; border-radius: 0 var(--xp-radius-card) var(--xp-radius-card) 0; background: linear-gradient(to left, var(--xp-border-strong), transparent); }
28
+ .xp-data-table-frame.has-left::before, .xp-data-table-frame.has-right::after { opacity: 1; }
29
+ .xp-data-table { width: 100%; border-collapse: separate; border-spacing: 0; font: 400 14px/20px var(--xp-font); }
30
+ .xp-data-table caption { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
31
+ .xp-data-table th, .xp-data-table td { padding: 12px 14px; white-space: nowrap; border-bottom: 1px solid var(--xp-border); text-align: left; }
32
+ .xp-data-table thead th { position: sticky; top: 0; z-index: 1; background: var(--xp-surface); font: var(--xp-text-small); color: var(--xp-text-2); }
33
+ .xp-data-table tr > :first-child { position: sticky; left: 0; z-index: 1; background: var(--xp-surface); }
34
+ .xp-data-table thead tr > :first-child { z-index: 2; }
35
+ .xp-data-table tbody th { font-weight: 400; }
36
+ .xp-data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
37
+ .xp-data-table .muted { color: var(--xp-text-3); }
38
+ .xp-data-table tr:last-child > * { border-bottom: 0; }
39
+ .xp-data-table tr.is-lead > * { background: var(--xp-surface-2); font-weight: 600; }
40
+ .xp-results-group { display: inline-flex; align-items: center; gap: 8px; }
41
+ .xp-results-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; flex: none; }
42
+ .xp-results-panel { border: 1px solid var(--xp-border); border-radius: var(--xp-radius-card); background: var(--xp-surface); min-width: 0; }
43
+ .xp-results-panel > summary { padding: 16px 20px; cursor: pointer; font: var(--xp-text-title); }
44
+ .xp-results-panel > summary:focus-visible { outline: 2px solid var(--xp-focus); outline-offset: 2px; }
45
+ .xp-results-panel > summary .xp-quality-chip { margin-left: 12px; }
46
+ .xp-quality-row { padding: 14px 20px; border-top: 1px solid var(--xp-border); display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 14px; }
47
+ .xp-quality-row > :not(:first-child) { grid-column: 2; }
48
+ .xp-quality-row ul { margin: 0; padding-left: 20px; }
49
+ .xp-quality-detail, .xp-quality-next, .xp-results-cap-help { color: var(--xp-text-2); font: var(--xp-text-small); }
50
+ .xp-quality-chip { display: inline-flex; align-self: start; padding: 2px 8px; border-radius: var(--xp-radius-chip); font: var(--xp-text-small); color: var(--xp-success); background: var(--xp-success-bg); }
51
+ .xp-quality-chip--watch { color: var(--xp-warning); background: var(--xp-warning-bg); }
52
+ .xp-quality-chip--problem { color: var(--xp-error); background: var(--xp-error-bg); }
53
+ .xp-ci-chart { padding: 20px; overflow-x: auto; }
54
+ .xp-ci-chart svg { display: block; min-width: 560px; }
55
+ .xp-ci-chart ul { display: flex; flex-wrap: wrap; gap: 16px; list-style: none; margin: 0; padding: 0; font: var(--xp-text-small); }
56
+ .xp-preview-links { display: grid; gap: 12px; }
57
+ .xp-preview-row { display: flex; align-items: center; flex-wrap: wrap; justify-content: space-between; gap: 12px; border-bottom: 1px solid var(--xp-border); padding-bottom: 12px; }
58
+ @media (max-width: 720px) {
59
+ .xp-stat-tiles { grid-template-columns: minmax(0, 1fr); }
60
+ .xp-stat-tile + .xp-stat-tile { border-left: 0; border-top: 1px solid var(--xp-border); }
61
+ .xp-verdict-hero { padding: 20px; }
62
+ .xp-verdict-hero h2 { font-size: 24px; line-height: 30px; }
63
+ }
64
+ .xp-results-as-of { color: var(--xp-text-2); }
@@ -66,6 +66,9 @@ export interface ArmRow {
66
66
  n: string;
67
67
  value: string;
68
68
  capped: CappedCellModel;
69
+ rate?: string;
70
+ lift?: string;
71
+ chanceToWin?: string;
69
72
  baseline?: string;
70
73
  comparison?: ComparisonModel;
71
74
  }
@@ -76,7 +79,7 @@ export declare function armRows({ snapshot, phase, metricId }: {
76
79
  }): ArmRow[];
77
80
  export declare function guardrailChips(snapshot: Snapshot): {
78
81
  name: string;
79
- status: "Failing" | "OK" | "Watch" | "Too little data";
82
+ status: "OK" | "Watch" | "Failing" | "Too little data";
80
83
  }[];
81
84
  interface RoundLineInput {
82
85
  snapshot: DisplaySnapshot;
@@ -85,6 +88,7 @@ interface RoundLineInput {
85
88
  }
86
89
  export declare function powerLine({ snapshot, phaseKind, status }: RoundLineInput): string | null;
87
90
  export interface ResultsContext {
91
+ status?: string;
88
92
  phase?: PhaseSummary;
89
93
  minExposuresPerArm?: number;
90
94
  inLayer?: boolean;
@@ -92,7 +96,7 @@ export interface ResultsContext {
92
96
  allocation?: number;
93
97
  }
94
98
  /** Only selects stored counts; never estimates sample sizes or power in the UI. */
95
- export declare function collectingLine({ snapshot, phaseKind, status }: RoundLineInput, ctx?: ResultsContext): string | null;
99
+ export declare function collectingLine({ snapshot, phaseKind }: RoundLineInput, ctx?: ResultsContext): string | null;
96
100
  export interface DataQualityItem {
97
101
  id: string;
98
102
  message: string;