@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,23 +1,25 @@
1
1
  export declare const GOALS_COPY: {
2
2
  readonly title: "Goals";
3
+ readonly goal: "Goal";
3
4
  readonly newGoal: "New goal";
4
5
  readonly name: "Name";
5
6
  readonly source: "Measured by";
6
7
  readonly directionColumn: "Better when";
7
8
  readonly direction: "Better when it goes";
8
- readonly increase: "Goes up";
9
- readonly decrease: "Goes down";
9
+ readonly increase: "More is better";
10
+ readonly decrease: "Less is better";
10
11
  readonly usedBy: "Used by";
11
12
  readonly status: "Status";
12
13
  readonly inUse: "In use";
13
- readonly unused: "Not used";
14
- readonly empty: "A goal is an outcome you want a test to improve, such as a registration or a gift.";
14
+ readonly unused: "Not used yet";
15
+ readonly empty: "No goals yet. A goal is what a test tries to improve.";
15
16
  readonly loading: "Loading goals…";
16
17
  readonly loadError: "Couldn't load goals. Try again.";
17
18
  readonly retry: "Try again";
18
19
  readonly slug: "Short name";
19
20
  readonly slugHelp: "A unique short name for this goal.";
20
21
  readonly slugLocked: "The short name stays the same once a test uses this goal.";
22
+ readonly sourceLocked: "What this goal measures stays the same once a test uses it.";
21
23
  readonly chooseSource: "Choose an outcome";
22
24
  readonly window: "Count results for (hours)";
23
25
  readonly minimum: "Minimum completions before deciding";
@@ -33,12 +35,25 @@ export declare const GOALS_COPY: {
33
35
  readonly save: "Save";
34
36
  readonly saving: "Saving…";
35
37
  readonly cancel: "Cancel";
36
- readonly remove: "Delete";
38
+ readonly remove: "Delete goal";
37
39
  readonly thresholdError: "Enter a percentage of zero or more, or leave blank for 5%.";
38
40
  readonly deleting: "Deleting…";
39
41
  readonly saveError: "Couldn't save the goal. Try again.";
40
42
  readonly deleteError: "Couldn't delete the goal. Try again.";
41
43
  readonly breadcrumb: "Breadcrumb";
42
- readonly missing: "This goal could not be found.";
44
+ readonly missing: "This goal no longer exists.";
45
+ readonly notFound: "This goal no longer exists.";
46
+ readonly backToTest: "Back to the test";
47
+ readonly useGoal: "Use this goal";
48
+ readonly open: "Open";
49
+ readonly search: "Search goals";
50
+ readonly clearSearch: "Clear search";
51
+ readonly fields: "Goal details";
52
+ readonly deleteTitle: "Delete this goal?";
53
+ readonly deleteBody: "This cannot be undone.";
54
+ readonly confirmDelete: "Delete";
43
55
  };
44
56
  export declare function goalUsedBy(count: number): string;
57
+ export declare function goalInUse(count: number): string;
58
+ export declare function goalDeleteLocked(count: number): string;
59
+ export declare function goalsNoMatches(search: string): string;
@@ -1,23 +1,25 @@
1
1
  export const GOALS_COPY = {
2
2
  title: 'Goals',
3
+ goal: 'Goal',
3
4
  newGoal: 'New goal',
4
5
  name: 'Name',
5
6
  source: 'Measured by',
6
7
  directionColumn: 'Better when',
7
8
  direction: 'Better when it goes',
8
- increase: 'Goes up',
9
- decrease: 'Goes down',
9
+ increase: 'More is better',
10
+ decrease: 'Less is better',
10
11
  usedBy: 'Used by',
11
12
  status: 'Status',
12
13
  inUse: 'In use',
13
- unused: 'Not used',
14
- empty: 'A goal is an outcome you want a test to improve, such as a registration or a gift.',
14
+ unused: 'Not used yet',
15
+ empty: 'No goals yet. A goal is what a test tries to improve.',
15
16
  loading: 'Loading goals…',
16
17
  loadError: "Couldn't load goals. Try again.",
17
18
  retry: 'Try again',
18
19
  slug: 'Short name',
19
20
  slugHelp: 'A unique short name for this goal.',
20
21
  slugLocked: 'The short name stays the same once a test uses this goal.',
22
+ sourceLocked: 'What this goal measures stays the same once a test uses it.',
21
23
  chooseSource: 'Choose an outcome',
22
24
  window: 'Count results for (hours)',
23
25
  minimum: 'Minimum completions before deciding',
@@ -33,14 +35,33 @@ export const GOALS_COPY = {
33
35
  save: 'Save',
34
36
  saving: 'Saving…',
35
37
  cancel: 'Cancel',
36
- remove: 'Delete',
38
+ remove: 'Delete goal',
37
39
  thresholdError: 'Enter a percentage of zero or more, or leave blank for 5%.',
38
40
  deleting: 'Deleting…',
39
41
  saveError: "Couldn't save the goal. Try again.",
40
42
  deleteError: "Couldn't delete the goal. Try again.",
41
43
  breadcrumb: 'Breadcrumb',
42
- missing: 'This goal could not be found.'
44
+ missing: 'This goal no longer exists.',
45
+ notFound: 'This goal no longer exists.',
46
+ backToTest: 'Back to the test',
47
+ useGoal: 'Use this goal',
48
+ open: 'Open',
49
+ search: 'Search goals',
50
+ clearSearch: 'Clear search',
51
+ fields: 'Goal details',
52
+ deleteTitle: 'Delete this goal?',
53
+ deleteBody: 'This cannot be undone.',
54
+ confirmDelete: 'Delete'
43
55
  };
44
56
  export function goalUsedBy(count) {
45
57
  return `Used by ${count} ${count === 1 ? 'test' : 'tests'}`;
46
58
  }
59
+ export function goalInUse(count) {
60
+ return `In use by ${count} ${count === 1 ? 'test' : 'tests'}`;
61
+ }
62
+ export function goalDeleteLocked(count) {
63
+ return `${goalUsedBy(count)}. Remove it from those tests first.`;
64
+ }
65
+ export function goalsNoMatches(search) {
66
+ return `No goals match “${search}”.`;
67
+ }
@@ -1,4 +1,13 @@
1
+ export declare const PLACEMENT_FAILURE_COPY: {
2
+ readonly 'placements-failed': "Couldn't check where this test is used. Try again.";
3
+ readonly forbidden: "You don't have permission to check where this test is used.";
4
+ readonly 'not-found': "A page used by this test no longer exists. Choose another page.";
5
+ };
1
6
  export declare const READINESS_COPY: {
7
+ readonly label: "Readiness";
8
+ readonly addGoal: "Add a goal";
9
+ readonly needsAttention: "Needs attention";
10
+ readonly missingVersions: "This test is missing its saved versions. Open the test and check its setup before changing this page.";
2
11
  readonly ready: "Ready to start.";
3
12
  readonly saveFirst: "Save your changes first.";
4
13
  readonly saving: "Saving…";
@@ -24,14 +33,21 @@ export declare const READINESS_COPY: {
24
33
  readonly noReach: "Enter how many people reach this per day.";
25
34
  readonly full: "This test's group is full. Lower how many people take part, or create the test again without the group.";
26
35
  readonly differentPeople: "This test's group counts different people. Create the test again without the group.";
36
+ readonly uncheckedPages: "Version pages aren't checked; make sure each one is published.";
27
37
  readonly noTargets: "Add a page address for each version.";
28
38
  readonly pageVisitors: "Whole-page tests count visitors. Create the test again counting visitors.";
39
+ readonly blockPathRule: "Remove the page-path rule in Who takes part; page block tests run on their page.";
40
+ readonly removeRule: "Remove rule";
29
41
  readonly ruleFallback: "check the value";
30
42
  readonly versionFallback: "check the group settings";
31
43
  readonly groupFallback: "each version";
32
44
  readonly parameterFallback: "each setting";
33
45
  readonly attributeFallback: "this attribute";
34
46
  };
47
+ export declare const unsupportedContentCopy: (page: string) => string;
48
+ export declare const unpublishedPageCopy: (path: string) => string;
49
+ /** Old responses may include raw host errors; unknown strings use authored copy. */
50
+ export declare const placementFailureCopy: (reason: unknown) => "Couldn't check where this test is used. Try again." | "You don't have permission to check where this test is used." | "A page used by this test no longer exists. Choose another page.";
35
51
  export declare const nextCopy: (sentence: string) => string;
36
52
  export declare const versionsNext: (detail: string) => string;
37
53
  export declare const contentNext: (group: string) => string;
@@ -43,3 +59,6 @@ export declare const attributeNext: (attribute: string) => string;
43
59
  export declare const stoppedCopy: (date: string | null) => string;
44
60
  export declare const decidedCopy: (date: string | null, winner: string) => string;
45
61
  export declare const runningCopy: (date: string | null, people: number | null, days: number | null) => string;
62
+ export declare const pageGuardCopy: (name: string, status: "running" | "decided" | "archived") => string;
63
+ export declare const versionPageUnavailableCopy: (path: string, status?: string) => string;
64
+ export declare const versionPageUncheckedCopy: (path: string, status?: string) => string;
@@ -1,4 +1,13 @@
1
+ export const PLACEMENT_FAILURE_COPY = {
2
+ 'placements-failed': "Couldn't check where this test is used. Try again.",
3
+ forbidden: "You don't have permission to check where this test is used.",
4
+ 'not-found': "A page used by this test no longer exists. Choose another page."
5
+ };
1
6
  export const READINESS_COPY = {
7
+ label: 'Readiness',
8
+ addGoal: 'Add a goal',
9
+ needsAttention: 'Needs attention',
10
+ missingVersions: 'This test is missing its saved versions. Open the test and check its setup before changing this page.',
2
11
  ready: 'Ready to start.',
3
12
  saveFirst: 'Save your changes first.',
4
13
  saving: 'Saving…',
@@ -24,14 +33,21 @@ export const READINESS_COPY = {
24
33
  noReach: 'Enter how many people reach this per day.',
25
34
  full: "This test's group is full. Lower how many people take part, or create the test again without the group.",
26
35
  differentPeople: "This test's group counts different people. Create the test again without the group.",
36
+ uncheckedPages: "Version pages aren't checked; make sure each one is published.",
27
37
  noTargets: 'Add a page address for each version.',
28
38
  pageVisitors: 'Whole-page tests count visitors. Create the test again counting visitors.',
39
+ blockPathRule: 'Remove the page-path rule in Who takes part; page block tests run on their page.',
40
+ // Next steps repeat the button label verbatim (testPage.ts removeRule).
41
+ removeRule: 'Remove rule',
29
42
  ruleFallback: 'check the value',
30
43
  versionFallback: 'check the group settings',
31
44
  groupFallback: 'each version',
32
45
  parameterFallback: 'each setting',
33
46
  attributeFallback: 'this attribute'
34
47
  };
48
+ export const unsupportedContentCopy = (page)=>`${page} has more than one language, so Make it the content isn't available for it; you'll copy the winning version by hand.`;
49
+ export const unpublishedPageCopy = (path)=>`${path} isn't a published page. Publish it, or pick another page.`;
50
+ /** Old responses may include raw host errors; unknown strings use authored copy. */ export const placementFailureCopy = (reason)=>PLACEMENT_FAILURE_COPY[typeof reason === 'string' && Object.hasOwn(PLACEMENT_FAILURE_COPY, reason) ? reason : 'placements-failed'];
35
51
  const withoutPeriod = (value)=>value.trim().replace(/[.!?]+$/, '');
36
52
  export const nextCopy = (sentence)=>`Next: ${sentence}`;
37
53
  export const versionsNext = (detail)=>`Fix the versions: ${withoutPeriod(detail)}.`;
@@ -48,3 +64,6 @@ export const runningCopy = (date, people, days)=>[
48
64
  people === null ? null : `${people.toLocaleString('en-US')} people so far`,
49
65
  days === null ? null : `about ${days} days to go`
50
66
  ].filter(Boolean).join(' · ');
67
+ export const pageGuardCopy = (name, status)=>status === 'archived' ? `This page is shown at other addresses because the finished test "${name}" made it the winner. To free it, open the test and choose "Release pages".` : status === 'decided' ? `This page is part of the decided test "${name}". Choose "Make it the content" or "Discard winner" on the test before you delete, rename or unpublish it.` : `This page is part of the running test "${name}". Stop the test before you delete, rename or unpublish it.`;
68
+ export const versionPageUnavailableCopy = (path, status = 'running')=>`${path} isn't published, so visitors assigned to it see an error. Republish it, or ${status === 'decided' ? 'discard the winner' : 'stop the test'}.`;
69
+ export const versionPageUncheckedCopy = (path, status = 'running')=>`Couldn't check whether ${path} is published. Check that it is still published, or ${status === 'decided' ? 'discard the winner' : 'stop the test'}.`;
@@ -19,8 +19,5 @@ export declare const mixedRecommendation: (better: string, worse: string) => str
19
19
  export declare const runningRecommendation: (date: string) => string;
20
20
  export declare const rolloutCollectingRecommendation: (winner: string) => string;
21
21
  export declare const rolloutReadoutRecommendation: (winner: string, lift: string) => string;
22
- export declare const RESULTS_SURFACE_COPY: {
23
- readonly missing: "This test couldn't be found.";
24
- };
25
22
  /** Matches the stored server finding; it is not a new statistical decision. */
26
23
  export declare const storedGuardrailFinding: (group: string, guardrail: string) => string;
@@ -19,7 +19,4 @@ export const mixedRecommendation = (better, worse)=>`Mixed: ${better} does bette
19
19
  export const runningRecommendation = (date)=>`No difference so far. Keep running until ${date}.`;
20
20
  export const rolloutCollectingRecommendation = (winner)=>`Since shipping ${winner}: still collecting data.`;
21
21
  export const rolloutReadoutRecommendation = (winner, lift)=>`Since shipping ${winner}: ${lift} compared with the holdout.`;
22
- export const RESULTS_SURFACE_COPY = {
23
- missing: "This test couldn't be found."
24
- };
25
22
  /** Matches the stored server finding; it is not a new statistical decision. */ export const storedGuardrailFinding = (group, guardrail)=>`Stop: ${group} harms ${guardrail}.`;
@@ -1,8 +1,35 @@
1
1
  export declare const RESULTS_COPY: {
2
+ readonly chooseGroup: "Choose a group";
3
+ readonly tests: "Tests";
4
+ readonly results: "Results";
5
+ readonly test: "Test";
6
+ readonly backToSetup: "Back to setup";
7
+ readonly days: "Days";
8
+ readonly methods: {
9
+ readonly sequential: "Sequential";
10
+ readonly bayesian: "Bayesian";
11
+ };
12
+ readonly asOfDecision: (date: string) => string;
13
+ readonly kinds: {
14
+ readonly binomial: "yes/no";
15
+ readonly count: "amount";
16
+ readonly revenue: "amount";
17
+ };
18
+ readonly qualityStates: {
19
+ readonly ok: "OK";
20
+ readonly watch: "Watch";
21
+ readonly problem: "Problem";
22
+ };
23
+ readonly qualityOK: "No data quality problems found.";
24
+ readonly previews: "Preview links";
25
+ readonly releasePages: "Release pages";
26
+ readonly releasePagesBody: "Every address shows its own page again. The result stays recorded.";
27
+ readonly you: "you";
2
28
  readonly group: "Group";
3
29
  readonly people: "People";
4
30
  readonly conversions: "Conversions";
5
- readonly mean: "Mean";
31
+ readonly average: "Average";
32
+ readonly rate: "Rate";
6
33
  readonly lift: "Lift";
7
34
  readonly ci: "Confidence interval";
8
35
  readonly adjustedCI: "Adjusted confidence interval";
@@ -40,7 +67,17 @@ export declare const RESULTS_COPY: {
40
67
  readonly tooFew: "Too few people have seen the compared groups.";
41
68
  readonly tooFewNext: "Keep collecting results until each compared group reaches the planned minimum.";
42
69
  readonly layerFull: "The layer has fewer slices reserved than the requested allocation.";
43
- readonly layerNext: "Free slices in the layer, then raise participation from the actions panel.";
70
+ readonly layerNext: "Free slices in the layer, then use \"Let more people in\".";
71
+ readonly unavailable: {
72
+ 'source-failed': string;
73
+ 'source-unavailable': string;
74
+ 'unit-type-unavailable': string;
75
+ 'non-finite-values': string;
76
+ 'non-finite-covariates': string;
77
+ budget: string;
78
+ 'not-supplied': string;
79
+ 'analysis-failed': string;
80
+ };
44
81
  readonly unavailableNext: "Recompute; if it persists, contact a developer.";
45
82
  readonly loading: "Loading results…";
46
83
  readonly refreshing: "Refreshing…";
@@ -57,6 +94,7 @@ export declare const RESULTS_COPY: {
57
94
  readonly chart: "Confidence interval over time";
58
95
  readonly noHistory: "Not enough history yet.";
59
96
  };
97
+ export declare const pagesReleasedCopy: (date: string, name?: string) => string;
60
98
  export declare const roundLabel: (round: number, kind: string) => string;
61
99
  export declare const decidedTitle: (winner: string) => string;
62
100
  export declare const shippingTitle: (winner: string) => string;
@@ -75,3 +113,4 @@ export declare const conflictCopy: (share: string) => string;
75
113
  export declare const metricUnavailable: (name: string, reason: string) => string;
76
114
  export declare const chartSummary: (metric: string, groups: string, from: string, to: string, changes?: string[]) => string;
77
115
  export declare const contentChangeTitle: (date: string) => string;
116
+ export declare const daysOfPlan: (days: string, planned: string) => string;
@@ -1,8 +1,35 @@
1
1
  export const RESULTS_COPY = {
2
+ chooseGroup: 'Choose a group',
3
+ tests: 'Tests',
4
+ results: 'Results',
5
+ test: 'Test',
6
+ backToSetup: 'Back to setup',
7
+ days: 'Days',
8
+ methods: {
9
+ sequential: 'Sequential',
10
+ bayesian: 'Bayesian'
11
+ },
12
+ asOfDecision: (date)=>`as of the decision, ${date}`,
13
+ kinds: {
14
+ binomial: 'yes/no',
15
+ count: 'amount',
16
+ revenue: 'amount'
17
+ },
18
+ qualityStates: {
19
+ ok: 'OK',
20
+ watch: 'Watch',
21
+ problem: 'Problem'
22
+ },
23
+ qualityOK: 'No data quality problems found.',
24
+ previews: 'Preview links',
25
+ releasePages: 'Release pages',
26
+ releasePagesBody: 'Every address shows its own page again. The result stays recorded.',
27
+ you: 'you',
2
28
  group: 'Group',
3
29
  people: 'People',
4
30
  conversions: 'Conversions',
5
- mean: 'Mean',
31
+ average: 'Average',
32
+ rate: 'Rate',
6
33
  lift: 'Lift',
7
34
  ci: 'Confidence interval',
8
35
  adjustedCI: 'Adjusted confidence interval',
@@ -40,7 +67,17 @@ export const RESULTS_COPY = {
40
67
  tooFew: 'Too few people have seen the compared groups.',
41
68
  tooFewNext: 'Keep collecting results until each compared group reaches the planned minimum.',
42
69
  layerFull: 'The layer has fewer slices reserved than the requested allocation.',
43
- layerNext: 'Free slices in the layer, then raise participation from the actions panel.',
70
+ layerNext: 'Free slices in the layer, then use "Let more people in".',
71
+ unavailable: {
72
+ 'source-failed': "couldn't be read this time; the next results run will try again.",
73
+ 'source-unavailable': "can't be read because its data source is no longer available. Ask a developer to check this goal.",
74
+ 'unit-type-unavailable': "can't be read for the people counted in this test. Ask a developer to check this goal.",
75
+ 'non-finite-values': "has values that can't be used. Ask a developer to check this goal's data.",
76
+ 'non-finite-covariates': "has earlier values that can't be used. Ask a developer to check this goal's data.",
77
+ budget: "couldn't finish in time; the next results run will try again.",
78
+ 'not-supplied': "has no data for this results run; the next results run will try again.",
79
+ 'analysis-failed': "couldn't be calculated this time; the next results run will try again."
80
+ },
44
81
  unavailableNext: 'Recompute; if it persists, contact a developer.',
45
82
  loading: 'Loading results…',
46
83
  refreshing: 'Refreshing…',
@@ -57,6 +94,7 @@ export const RESULTS_COPY = {
57
94
  chart: 'Confidence interval over time',
58
95
  noHistory: 'Not enough history yet.'
59
96
  };
97
+ export const pagesReleasedCopy = (date, name)=>`Pages released ${date}${name ? ` by ${name}` : ''}`;
60
98
  export const roundLabel = (round, kind)=>`Round ${round} · ${kind}`;
61
99
  export const decidedTitle = (winner)=>`Decided: ${winner}`;
62
100
  export const shippingTitle = (winner)=>`Since shipping ${winner}`;
@@ -72,9 +110,10 @@ export const shareCopy = (label, expected, observed)=>`${label}: expected ${expe
72
110
  export const exclusionCopy = (count, share)=>`${count} excluded (${share}).`;
73
111
  export const ignoredCopy = (count)=>`${count} ignored.`;
74
112
  export const conflictCopy = (share)=>`${share} with identity conflicts.`;
75
- export const metricUnavailable = (name, reason)=>`${name} is unavailable: ${reason}`;
113
+ export const metricUnavailable = (name, reason)=>`${name} ${RESULTS_COPY.unavailable[Object.hasOwn(RESULTS_COPY.unavailable, reason) ? reason : 'source-failed']}`;
76
114
  export const chartSummary = (metric, groups, from, to, changes = [])=>`${metric}: lift and confidence intervals for ${groups}, ${from} to ${to}.${changes.length ? ` Content changed on ${new Intl.ListFormat('en-US', {
77
115
  style: 'long',
78
116
  type: 'conjunction'
79
117
  }).format(changes)}.` : ''}`;
80
118
  export const contentChangeTitle = (date)=>`Content changed ${date} by an editor`;
119
+ export const daysOfPlan = (days, planned)=>`${days} of ${planned}`;
@@ -13,5 +13,5 @@ export declare const REVIEW_COPY: {
13
13
  readonly metric: "Metric";
14
14
  readonly chooseMetric: "Choose a metric";
15
15
  readonly loadingMetrics: "Loading metrics…";
16
- readonly noMetrics: "All available metrics are already on this experiment.";
16
+ readonly noMetrics: "All available goals are already on this test.";
17
17
  };
@@ -13,5 +13,5 @@ export const REVIEW_COPY = {
13
13
  metric: 'Metric',
14
14
  chooseMetric: 'Choose a metric',
15
15
  loadingMetrics: 'Loading metrics…',
16
- noMetrics: 'All available metrics are already on this experiment.'
16
+ noMetrics: 'All available goals are already on this test.'
17
17
  };
@@ -1,4 +1,6 @@
1
1
  export declare const SETTING_COPY: {
2
+ readonly valuesReady: "Values ready";
3
+ readonly setValues: "Set values";
2
4
  readonly setting: "Setting";
3
5
  readonly choose: "Choose the setting first.";
4
6
  readonly current: "Current: {value}";
@@ -1,4 +1,6 @@
1
1
  export const SETTING_COPY = {
2
+ valuesReady: 'Values ready',
3
+ setValues: 'Set values',
2
4
  setting: 'Setting',
3
5
  choose: 'Choose the setting first.',
4
6
  current: 'Current: {value}',
@@ -1,5 +1,7 @@
1
1
  export declare const SURFACE_COPY: {
2
2
  readonly title: "Tests";
3
+ readonly test: "Test";
4
+ readonly resultsTitle: "Results";
3
5
  readonly newTest: "New test";
4
6
  readonly goals: "Goals";
5
7
  readonly search: "Search tests";
@@ -15,8 +17,8 @@ export declare const SURFACE_COPY: {
15
17
  readonly loadError: "Tests could not be loaded. Please try again.";
16
18
  readonly summaryError: "Some test summaries could not be loaded. Please try again.";
17
19
  readonly retry: "Try again";
18
- readonly empty: "Test a change to see what works best for the people who visit your pages.";
19
- readonly noMatches: "No tests match your search.";
20
+ readonly empty: "Create a test to learn what works.";
21
+ readonly clear: "Clear";
20
22
  readonly groups: readonly ["Needs attention", "Running", "Ready to start", "Draft", "Decided", "Archived"];
21
23
  readonly kinds: {
22
24
  readonly block: "Page block";
@@ -25,12 +27,12 @@ export declare const SURFACE_COPY: {
25
27
  readonly page: "Whole page";
26
28
  };
27
29
  readonly ready: "Ready to start";
28
- readonly next: "Next: finish setting up";
30
+ readonly next: "Review setup";
29
31
  readonly continue: "Continue setup";
30
32
  readonly results: "View results";
31
33
  readonly open: "Open";
32
34
  readonly health: {
33
- readonly red: "Stop and check";
35
+ readonly red: "Needs attention";
34
36
  readonly amber: "Check data";
35
37
  readonly green: "On track";
36
38
  };
@@ -38,3 +40,4 @@ export declare const SURFACE_COPY: {
38
40
  };
39
41
  export declare function runningLine(days: string, planned: string, people: string): string;
40
42
  export declare function decidedLine(date: string, winner: string): string;
43
+ export declare function noMatchesLine(query: string): string;
@@ -1,5 +1,7 @@
1
1
  export const SURFACE_COPY = {
2
2
  title: 'Tests',
3
+ test: 'Test',
4
+ resultsTitle: 'Results',
3
5
  newTest: 'New test',
4
6
  goals: 'Goals',
5
7
  search: 'Search tests',
@@ -15,8 +17,8 @@ export const SURFACE_COPY = {
15
17
  loadError: 'Tests could not be loaded. Please try again.',
16
18
  summaryError: 'Some test summaries could not be loaded. Please try again.',
17
19
  retry: 'Try again',
18
- empty: 'Test a change to see what works best for the people who visit your pages.',
19
- noMatches: 'No tests match your search.',
20
+ empty: 'Create a test to learn what works.',
21
+ clear: 'Clear',
20
22
  groups: [
21
23
  'Needs attention',
22
24
  'Running',
@@ -32,12 +34,12 @@ export const SURFACE_COPY = {
32
34
  page: 'Whole page'
33
35
  },
34
36
  ready: 'Ready to start',
35
- next: 'Next: finish setting up',
37
+ next: 'Review setup',
36
38
  continue: 'Continue setup',
37
39
  results: 'View results',
38
40
  open: 'Open',
39
41
  health: {
40
- red: 'Stop and check',
42
+ red: 'Needs attention',
41
43
  amber: 'Check data',
42
44
  green: 'On track'
43
45
  },
@@ -49,3 +51,6 @@ export function runningLine(days, planned, people) {
49
51
  export function decidedLine(date, winner) {
50
52
  return `Decided ${date}: ${winner}`;
51
53
  }
54
+ export function noMatchesLine(query) {
55
+ return `No tests match "${query}".`;
56
+ }
@@ -1,4 +1,6 @@
1
1
  export declare const TEST_PAGE: {
2
+ readonly staleEdit: "Someone else changed this test. Reload to see their changes.";
3
+ readonly reload: "Reload";
2
4
  readonly loading: "Loading test…";
3
5
  readonly forbidden: "You don't have access to this test.";
4
6
  readonly missing: "This test no longer exists.";
@@ -6,6 +8,11 @@ export declare const TEST_PAGE: {
6
8
  readonly retry: "Try again";
7
9
  readonly name: "Test name";
8
10
  readonly results: "Results";
11
+ readonly tests: "Tests";
12
+ readonly test: "Test";
13
+ readonly navigation: "Sections";
14
+ readonly completePrefix: "Complete: ";
15
+ readonly incompletePrefix: "Incomplete: ";
9
16
  readonly complete: "Complete";
10
17
  readonly incomplete: "Incomplete";
11
18
  readonly completeMark: "✓";
@@ -31,6 +38,9 @@ export declare const TEST_PAGE: {
31
38
  readonly openPage: "Open the page";
32
39
  readonly editedOnPage: "Versions are edited on the page.";
33
40
  readonly editOnPage: "Edit on page";
41
+ readonly empty: "Empty";
42
+ readonly pageReady: "Page ready";
43
+ readonly addPageAddress: "Add a page address";
34
44
  readonly ready: "Content ready";
35
45
  readonly emptySlot: "Nothing in this slot yet";
36
46
  readonly pageBinding: "Each version is a whole page at its own address.";
@@ -62,6 +72,7 @@ export declare const TEST_PAGE: {
62
72
  readonly rulesSummary: "Only people matching these rules.";
63
73
  readonly addRule: "Add a rule";
64
74
  readonly removeRule: "Remove rule";
75
+ readonly blockPathRule: "This rule no longer applies to page block tests; remove it.";
65
76
  readonly attribute: "Attribute";
66
77
  readonly comparison: "Comparison";
67
78
  readonly value: "Value";
@@ -86,3 +97,4 @@ export declare const NUMBER_COMPARISONS: {
86
97
  readonly lt: "is less than";
87
98
  readonly lte: "is at most";
88
99
  };
100
+ export declare const placementCount: (count: number) => string;
@@ -1,4 +1,6 @@
1
1
  export const TEST_PAGE = {
2
+ staleEdit: 'Someone else changed this test. Reload to see their changes.',
3
+ reload: 'Reload',
2
4
  loading: 'Loading test…',
3
5
  forbidden: "You don't have access to this test.",
4
6
  missing: 'This test no longer exists.',
@@ -6,6 +8,11 @@ export const TEST_PAGE = {
6
8
  retry: 'Try again',
7
9
  name: 'Test name',
8
10
  results: 'Results',
11
+ tests: 'Tests',
12
+ test: 'Test',
13
+ navigation: 'Sections',
14
+ completePrefix: 'Complete: ',
15
+ incompletePrefix: 'Incomplete: ',
9
16
  complete: 'Complete',
10
17
  incomplete: 'Incomplete',
11
18
  completeMark: '✓',
@@ -31,6 +38,9 @@ export const TEST_PAGE = {
31
38
  openPage: 'Open the page',
32
39
  editedOnPage: 'Versions are edited on the page.',
33
40
  editOnPage: 'Edit on page',
41
+ empty: 'Empty',
42
+ pageReady: 'Page ready',
43
+ addPageAddress: 'Add a page address',
34
44
  ready: 'Content ready',
35
45
  emptySlot: 'Nothing in this slot yet',
36
46
  pageBinding: 'Each version is a whole page at its own address.',
@@ -62,6 +72,7 @@ export const TEST_PAGE = {
62
72
  rulesSummary: 'Only people matching these rules.',
63
73
  addRule: 'Add a rule',
64
74
  removeRule: 'Remove rule',
75
+ blockPathRule: 'This rule no longer applies to page block tests; remove it.',
65
76
  attribute: 'Attribute',
66
77
  comparison: 'Comparison',
67
78
  value: 'Value',
@@ -86,3 +97,4 @@ export const NUMBER_COMPARISONS = {
86
97
  lt: 'is less than',
87
98
  lte: 'is at most'
88
99
  };
100
+ export const placementCount = (count)=>` (placed ${count} times)`;
@@ -0,0 +1,2 @@
1
+ /** Shared calendar date for admin copy, chart axes and tooltips. */
2
+ export declare function formatDate(value: unknown): string;
@@ -0,0 +1,10 @@
1
+ const formatter = new Intl.DateTimeFormat('en-GB', {
2
+ day: 'numeric',
3
+ month: 'short',
4
+ year: 'numeric',
5
+ timeZone: 'UTC'
6
+ });
7
+ /** Shared calendar date for admin copy, chart axes and tooltips. */ export function formatDate(value) {
8
+ const date = value instanceof Date ? value : typeof value === 'string' || typeof value === 'number' ? new Date(value) : null;
9
+ return date && Number.isFinite(date.valueOf()) ? formatter.format(date) : '—';
10
+ }
@@ -1,12 +1,7 @@
1
1
  import type { ExperimentKind, Status } from '../types/contracts.js';
2
2
  import type { VerdictCode } from '../types/snapshot.js';
3
- export declare const ARM_LABELS: {
4
- control: string;
5
- variantA: string;
6
- variantB: string;
7
- variantC: string;
8
- holdout: string;
9
- };
3
+ import { ARM_LABELS } from '../labels/arms.js';
4
+ export { ARM_LABELS };
10
5
  export declare const STATUS_LABELS: {
11
6
  draft: string;
12
7
  running: string;
@@ -1,10 +1,5 @@
1
- export const ARM_LABELS = {
2
- control: 'Original',
3
- variantA: 'Variant A',
4
- variantB: 'Variant B',
5
- variantC: 'Variant C',
6
- holdout: 'Holdout'
7
- };
1
+ import { ARM_LABELS } from '../labels/arms.js';
2
+ export { ARM_LABELS };
8
3
  export const STATUS_LABELS = {
9
4
  draft: 'Draft',
10
5
  running: 'Running',
@@ -1,9 +1,9 @@
1
1
  import type { PreflightResult } from '../types/endpoints.js';
2
2
  type Placement = PreflightResult['placements'][number];
3
- type PreviewPage = Pick<Placement, 'collection' | 'id' | 'title' | 'url'> & {
3
+ type PreviewPage = Placement & {
4
4
  key: string;
5
5
  slotCount: number;
6
6
  };
7
7
  /** Preview URLs identify pages; counts use the most placements in any one version. */
8
- export declare function previewPages(placements: readonly Placement[]): PreviewPage[];
8
+ export declare function previewPages(placements: readonly Placement[], flagPoint?: string): PreviewPage[];
9
9
  export {};