@delmaredigital/payload-experiments 0.2.0-rc.7 → 0.3.0-rc.4
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/README.md +202 -26
- package/dist/admin/PreviewLinks.d.ts +2 -1
- package/dist/admin/PreviewLinks.js +50 -21
- package/dist/admin/TestsNavLink.d.ts +3 -1
- package/dist/admin/TestsNavLink.js +2 -2
- package/dist/admin/actions/ConfirmDialog.d.ts +7 -4
- package/dist/admin/actions/ConfirmDialog.js +37 -82
- package/dist/admin/actions/DecideDialog.d.ts +3 -1
- package/dist/admin/actions/DecideDialog.js +30 -13
- package/dist/admin/actions/MakeContentResult.d.ts +13 -2
- package/dist/admin/actions/MakeContentResult.js +115 -16
- package/dist/admin/actions/actions.model.d.ts +2 -4
- package/dist/admin/actions/actions.model.js +2 -3
- package/dist/admin/allocation.model.js +3 -5
- package/dist/admin/api.d.ts +10 -4
- package/dist/admin/api.js +11 -7
- package/dist/admin/armSelect/ArmSelectField.js +14 -22
- package/dist/admin/arms/arms.model.d.ts +1 -21
- package/dist/admin/arms/arms.model.js +1 -153
- package/dist/admin/copy/actions.d.ts +39 -3
- package/dist/admin/copy/actions.js +40 -4
- package/dist/admin/copy/armSelect.js +5 -5
- package/dist/admin/copy/arms.d.ts +1 -6
- package/dist/admin/copy/arms.js +1 -16
- package/dist/admin/copy/audience.d.ts +2 -1
- package/dist/admin/copy/audience.js +3 -2
- package/dist/admin/copy/common.d.ts +13 -6
- package/dist/admin/copy/common.js +14 -8
- package/dist/admin/copy/goals.d.ts +21 -6
- package/dist/admin/copy/goals.js +27 -6
- package/dist/admin/copy/readiness.d.ts +22 -0
- package/dist/admin/copy/readiness.js +21 -0
- package/dist/admin/copy/recommendation.d.ts +0 -3
- package/dist/admin/copy/recommendation.js +0 -3
- package/dist/admin/copy/results.d.ts +43 -2
- package/dist/admin/copy/results.js +44 -3
- package/dist/admin/copy/review.d.ts +2 -2
- package/dist/admin/copy/review.js +2 -2
- package/dist/admin/copy/setting.d.ts +2 -0
- package/dist/admin/copy/setting.js +2 -0
- package/dist/admin/copy/surface.d.ts +7 -5
- package/dist/admin/copy/surface.js +9 -5
- package/dist/admin/copy/testPage.d.ts +10 -0
- package/dist/admin/copy/testPage.js +10 -0
- package/dist/admin/format/date.d.ts +2 -0
- package/dist/admin/format/date.js +10 -0
- package/dist/admin/paths.d.ts +2 -1
- package/dist/admin/paths.js +2 -1
- package/dist/admin/previewLinks.model.d.ts +4 -2
- package/dist/admin/previewLinks.model.js +8 -7
- package/dist/admin/results/CiChart.js +11 -21
- package/dist/admin/results/DataQualityPanel.d.ts +4 -2
- package/dist/admin/results/DataQualityPanel.js +30 -17
- package/dist/admin/results/DataTable.d.ts +16 -0
- package/dist/admin/results/DataTable.js +152 -0
- package/dist/admin/results/StatTile.d.ts +7 -0
- package/dist/admin/results/StatTile.js +22 -0
- package/dist/admin/results/VerdictHero.d.ts +13 -0
- package/dist/admin/results/{VerdictCard.js → VerdictHero.js} +15 -12
- package/dist/admin/results/legacy.d.ts +16 -0
- package/dist/admin/results/legacy.js +27 -0
- package/dist/admin/results/releasePages.model.d.ts +17 -0
- package/dist/admin/results/releasePages.model.js +10 -0
- package/dist/admin/results/results.css +64 -0
- package/dist/admin/results/results.model.d.ts +11 -7
- package/dist/admin/results/results.model.js +24 -7
- package/dist/admin/results/snapshot.d.ts +14 -0
- package/dist/admin/results/snapshot.js +3 -0
- package/dist/admin/surface/ResultsRoute.d.ts +1 -1
- package/dist/admin/surface/ResultsRoute.js +59 -34
- package/dist/admin/surface/SurfaceShell.d.ts +11 -2
- package/dist/admin/surface/SurfaceShell.js +49 -14
- package/dist/admin/surface/TestsHome.d.ts +6 -1
- package/dist/admin/surface/TestsHome.js +182 -114
- package/dist/admin/surface/TestsSurface.js +56 -16
- package/dist/admin/surface/goals/GoalForm.js +341 -308
- package/dist/admin/surface/goals/GoalsList.js +123 -89
- package/dist/admin/surface/goals/data.d.ts +8 -2
- package/dist/admin/surface/goals/data.js +24 -16
- package/dist/admin/surface/goals/goals.css +10 -13
- package/dist/admin/surface/home.model.d.ts +8 -8
- package/dist/admin/surface/home.model.js +23 -12
- package/dist/admin/surface/newTest/NewTest.js +9 -9
- package/dist/admin/surface/pageBlock/parts.js +31 -26
- package/dist/admin/surface/readiness/ActionDialogs.js +47 -19
- package/dist/admin/surface/readiness/Banner.d.ts +3 -0
- package/dist/admin/surface/readiness/Banner.js +58 -33
- package/dist/admin/surface/readiness/SaveStatus.d.ts +1 -0
- package/dist/admin/surface/readiness/SaveStatus.js +6 -3
- package/dist/admin/surface/readiness/readiness.model.d.ts +2 -0
- package/dist/admin/surface/readiness/readiness.model.js +25 -9
- package/dist/admin/surface/readiness/useTransition.d.ts +1 -0
- package/dist/admin/surface/readiness/useTransition.js +2 -1
- package/dist/admin/surface/results/ReleasePages.d.ts +14 -0
- package/dist/admin/surface/results/ReleasePages.js +116 -0
- package/dist/admin/surface/results/ResultsBody.d.ts +11 -1
- package/dist/admin/surface/results/ResultsBody.js +277 -105
- package/dist/admin/surface/results/ResultsHeader.d.ts +10 -0
- package/dist/admin/surface/results/ResultsHeader.js +177 -0
- package/dist/admin/surface/results/recommendation.model.d.ts +3 -2
- package/dist/admin/surface/results/recommendation.model.js +12 -9
- package/dist/admin/surface/results/useResults.d.ts +21 -3
- package/dist/admin/surface/results/useResults.js +2 -1
- package/dist/admin/surface/setting/parts.js +75 -88
- package/dist/admin/surface/setting/setting.css +3 -15
- package/dist/admin/surface/surface.css +61 -47
- package/dist/admin/surface/test/AdvancedSection.js +55 -48
- package/dist/admin/surface/test/GoalSection.js +46 -47
- package/dist/admin/surface/test/LengthSection.js +46 -34
- package/dist/admin/surface/test/Rail.d.ts +4 -0
- package/dist/admin/surface/test/Rail.js +83 -0
- package/dist/admin/surface/test/ReadinessBar.d.ts +5 -0
- package/dist/admin/surface/test/ReadinessBar.js +33 -0
- package/dist/admin/surface/test/Section.d.ts +1 -1
- package/dist/admin/surface/test/Section.js +36 -16
- package/dist/admin/surface/test/TargetingSection.js +168 -142
- package/dist/admin/surface/test/TestPage.d.ts +2 -1
- package/dist/admin/surface/test/TestPage.js +146 -68
- package/dist/admin/surface/test/VersionsSection.js +151 -120
- package/dist/admin/surface/test/fields.d.ts +11 -4
- package/dist/admin/surface/test/fields.js +84 -85
- package/dist/admin/surface/test/jumpToSection.d.ts +3 -0
- package/dist/admin/surface/test/jumpToSection.js +10 -0
- package/dist/admin/surface/test/pageParts.js +9 -3
- package/dist/admin/surface/test/testPage.css +81 -14
- package/dist/admin/surface/test/testPage.model.d.ts +2 -3
- package/dist/admin/surface/test/testPage.model.js +1 -21
- package/dist/admin/surface/useTestDocument.js +12 -5
- package/dist/admin/targeting/targeting.model.d.ts +1 -3
- package/dist/admin/targeting/targeting.model.js +3 -8
- package/dist/admin/theme.css +115 -36
- package/dist/admin/theme.d.ts +38 -0
- package/dist/admin/theme.js +38 -1
- package/dist/admin/useApi.d.ts +17 -2
- package/dist/admin/useLayerUsage.js +14 -23
- package/dist/admin/views/ExperimentsRootView.js +12 -2
- package/dist/admin/views/TestsNavLinkServer.d.ts +2 -0
- package/dist/admin/views/TestsNavLinkServer.js +43 -0
- package/dist/arms/copy.d.ts +6 -0
- package/dist/arms/copy.js +16 -0
- package/dist/arms/model.d.ts +23 -0
- package/dist/arms/model.js +173 -0
- package/dist/collections/experiments/config.js +25 -0
- package/dist/collections/experiments/lockHook.js +3 -1
- package/dist/collections/identities.js +6 -1
- package/dist/collections/metrics.js +7 -0
- package/dist/collections/metricsGuards.d.ts +9 -0
- package/dist/collections/metricsGuards.js +33 -0
- package/dist/contentDone.d.ts +4 -0
- package/dist/contentDone.js +5 -0
- package/dist/db/appends.d.ts +6 -2
- package/dist/db/appends.js +10 -4
- package/dist/db/identities.d.ts +8 -7
- package/dist/db/identities.js +9 -6
- package/dist/db/locks.d.ts +6 -0
- package/dist/db/locks.js +13 -1
- package/dist/db/metricUsage.d.ts +19 -0
- package/dist/db/metricUsage.js +54 -0
- package/dist/db/names.d.ts +5 -0
- package/dist/db/names.js +5 -0
- package/dist/db/pageOccupancy.d.ts +12 -0
- package/dist/db/pageOccupancy.js +45 -0
- package/dist/db/publishedContent.d.ts +10 -0
- package/dist/db/publishedContent.js +43 -0
- package/dist/db/results.d.ts +2 -0
- package/dist/db/results.js +6 -2
- package/dist/db/snapshots.d.ts +18 -6
- package/dist/db/snapshots.js +25 -8
- package/dist/db/sweep.js +11 -6
- package/dist/endpoints/index.js +19 -1
- package/dist/endpoints/results.js +5 -0
- package/dist/endpoints/sanitizeReadinessDetail.d.ts +1 -0
- package/dist/endpoints/sanitizeReadinessDetail.js +2 -0
- package/dist/endpoints/summary.js +20 -2
- package/dist/endpoints/transitions.d.ts +15 -0
- package/dist/endpoints/transitions.js +36 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +28 -0
- package/dist/exports/adminRsc.d.ts +1 -0
- package/dist/exports/adminRsc.js +1 -0
- package/dist/exports/index.d.ts +2 -1
- package/dist/exports/index.js +1 -0
- package/dist/exports/puck.d.ts +2 -1
- package/dist/exports/puck.js +1 -1
- package/dist/exports/puckEditor.d.ts +4 -1
- package/dist/exports/puckEditor.js +3 -1
- package/dist/exports/rsc.d.ts +6 -1
- package/dist/exports/rsc.js +2 -0
- package/dist/hooks/pageGuard.d.ts +5 -0
- package/dist/hooks/pageGuard.js +139 -0
- package/dist/lib/fetchAllDocs.d.ts +16 -0
- package/dist/lib/fetchAllDocs.js +56 -0
- package/dist/log.js +6 -3
- package/dist/manifest/compile.d.ts +5 -0
- package/dist/manifest/compile.js +5 -1
- package/dist/options.js +16 -0
- package/dist/plugin.js +30 -2
- package/dist/puck/ExperimentPicker.js +47 -16
- package/dist/puck/ExperimentSlot.d.ts +51 -1
- package/dist/puck/ExperimentSlot.js +23 -12
- package/dist/puck/copy.d.ts +6 -5
- package/dist/puck/copy.js +6 -5
- package/dist/puck/editor/CreateExperimentDrawer.js +46 -56
- package/dist/puck/editor/ExperimentSlotEditor.d.ts +52 -1
- package/dist/puck/editor/ExperimentSlotEditor.js +292 -137
- package/dist/puck/editor/ResultsReadout.d.ts +6 -0
- package/dist/puck/editor/ResultsReadout.js +99 -0
- package/dist/puck/editor/VersionBuilder.d.ts +34 -0
- package/dist/puck/editor/VersionBuilder.js +317 -0
- package/dist/puck/editor/armWrites.d.ts +7 -0
- package/dist/puck/editor/armWrites.js +71 -0
- package/dist/puck/editor/armsCache.d.ts +14 -0
- package/dist/puck/editor/armsCache.js +78 -0
- package/dist/puck/editor/copy.d.ts +33 -1
- package/dist/puck/editor/copy.js +45 -8
- package/dist/puck/editor/createTest.d.ts +1 -1
- package/dist/puck/editor/createTest.js +25 -14
- package/dist/puck/editor/editor.chrome.css +121 -0
- package/dist/puck/editor/editor.css +288 -204
- package/dist/puck/editor/editor.model.d.ts +4 -1
- package/dist/puck/editor/editor.model.js +10 -7
- package/dist/puck/editor/experimentOutlinePlugin.d.ts +3 -0
- package/dist/puck/editor/experimentOutlinePlugin.js +89 -0
- package/dist/puck/experimentSlotField.d.ts +2 -0
- package/dist/puck/experimentSlotField.js +11 -3
- package/dist/puck/hostContext.d.ts +10 -0
- package/dist/puck/hostContext.js +12 -0
- package/dist/puck/routes.d.ts +12 -0
- package/dist/puck/routes.js +11 -0
- package/dist/puck/slotConfig.d.ts +1 -1
- package/dist/puck/slotConfig.js +2 -2
- package/dist/results/aggregate.js +4 -3
- package/dist/results/analyse.d.ts +4 -1
- package/dist/results/analyse.js +27 -11
- package/dist/results/cuped.js +3 -2
- package/dist/results/identityCredit.d.ts +15 -7
- package/dist/results/identityCredit.js +32 -33
- package/dist/results/rolloutUnits.js +2 -1
- package/dist/results/snapshot.js +8 -2
- package/dist/results/srm.js +2 -1
- package/dist/sanitizeReadinessDetail.d.ts +7 -0
- package/dist/sanitizeReadinessDetail.js +63 -0
- package/dist/server/linkIdentity.d.ts +10 -1
- package/dist/server/linkIdentity.js +17 -15
- package/dist/server/metadata.d.ts +5 -0
- package/dist/server/metadata.js +18 -3
- package/dist/server/normaliseContentRelationships.d.ts +7 -0
- package/dist/server/normaliseContentRelationships.js +62 -0
- package/dist/server/recordContentChange.d.ts +1 -1
- package/dist/server/recordContentChange.js +17 -8
- package/dist/server/runResults.d.ts +3 -2
- package/dist/server/runResults.js +157 -35
- package/dist/targeting/values.d.ts +4 -0
- package/dist/targeting/values.js +10 -0
- package/dist/transitions/addMetric.js +8 -0
- package/dist/transitions/archive.js +2 -3
- package/dist/transitions/checkStart.d.ts +10 -3
- package/dist/transitions/checkStart.js +25 -0
- package/dist/transitions/contentFields.d.ts +7 -0
- package/dist/transitions/contentFields.js +20 -0
- package/dist/transitions/decide.js +22 -2
- package/dist/transitions/dismissContentEntry.d.ts +8 -0
- package/dist/transitions/dismissContentEntry.js +45 -0
- package/dist/transitions/makeContent.d.ts +5 -2
- package/dist/transitions/makeContent.js +217 -118
- package/dist/transitions/phaseRecord.d.ts +8 -2
- package/dist/transitions/placements.d.ts +3 -6
- package/dist/transitions/placements.js +12 -1
- package/dist/transitions/preflightData.d.ts +9 -1
- package/dist/transitions/preflightData.js +138 -20
- package/dist/transitions/releasePages.d.ts +8 -0
- package/dist/transitions/releasePages.js +26 -0
- package/dist/transitions/restoreContentEntry.d.ts +8 -0
- package/dist/transitions/restoreContentEntry.js +47 -0
- package/dist/transitions/start.js +62 -7
- package/dist/types/contracts.d.ts +24 -4
- package/dist/types/endpoints.d.ts +34 -3
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/reasons.d.ts +3 -0
- package/dist/types/reasons.js +1 -0
- package/dist/types/snapshot.d.ts +6 -1
- package/dist/ui/Banner.d.ts +2 -0
- package/dist/ui/Banner.js +2 -0
- package/dist/ui/Breadcrumb.d.ts +7 -0
- package/dist/ui/Breadcrumb.js +25 -0
- package/dist/ui/Button.d.ts +15 -0
- package/dist/ui/Button.js +32 -0
- package/dist/ui/Card.d.ts +12 -0
- package/dist/ui/Card.js +40 -0
- package/dist/ui/Checkbox.d.ts +2 -0
- package/dist/ui/Checkbox.js +2 -0
- package/dist/{admin/components → ui}/ChipsInput.d.ts +4 -3
- package/dist/{admin/components → ui}/ChipsInput.js +20 -12
- package/dist/ui/Dialog.d.ts +13 -0
- package/dist/ui/Dialog.js +85 -0
- package/dist/ui/EmptyState.d.ts +2 -0
- package/dist/ui/EmptyState.js +2 -0
- package/dist/ui/Feedback.d.ts +24 -0
- package/dist/ui/Feedback.js +40 -0
- package/dist/ui/Inputs.d.ts +34 -0
- package/dist/ui/Inputs.js +225 -0
- package/dist/ui/NumberInput.d.ts +2 -0
- package/dist/ui/NumberInput.js +2 -0
- package/dist/ui/Range.d.ts +2 -0
- package/dist/ui/Range.js +2 -0
- package/dist/ui/SearchInput.d.ts +2 -0
- package/dist/ui/SearchInput.js +2 -0
- package/dist/ui/SectionCard.d.ts +2 -0
- package/dist/ui/SectionCard.js +2 -0
- package/dist/ui/Select.d.ts +2 -0
- package/dist/ui/Select.js +2 -0
- package/dist/ui/StatusChip.d.ts +2 -0
- package/dist/ui/StatusChip.js +2 -0
- package/dist/ui/Tabs.d.ts +16 -0
- package/dist/ui/Tabs.js +61 -0
- package/dist/ui/TextInput.d.ts +2 -0
- package/dist/ui/TextInput.js +2 -0
- package/dist/ui/Textarea.d.ts +2 -0
- package/dist/ui/Textarea.js +2 -0
- package/dist/ui/Toggle.d.ts +2 -0
- package/dist/ui/Toggle.js +2 -0
- package/dist/ui/accent.d.ts +40 -0
- package/dist/ui/accent.js +139 -0
- package/dist/ui/index.d.ts +9 -0
- package/dist/ui/index.js +9 -0
- package/dist/ui/ui.css +92 -0
- package/package.json +5 -2
- package/dist/admin/components/chipsInput.css +0 -11
- package/dist/admin/results/ArmTable.d.ts +0 -8
- package/dist/admin/results/ArmTable.js +0 -113
- package/dist/admin/results/VerdictCard.d.ts +0 -9
- package/dist/admin/surface/goals/GoalsBreadcrumb.d.ts +0 -5
- package/dist/admin/surface/goals/GoalsBreadcrumb.js +0 -47
- package/dist/admin/surface/test/TestHeader.d.ts +0 -4
- package/dist/admin/surface/test/TestHeader.js +0 -70
|
@@ -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
|
-
|
|
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(', '),
|
|
46
|
-
...new Set(model.markers.map((marker)=>
|
|
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:
|
|
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:
|
|
71
|
+
children: formatDate(to)
|
|
82
72
|
}),
|
|
83
|
-
model.variants.map((variant
|
|
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 =
|
|
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(
|
|
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
|
|
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:
|
|
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
|
-
|
|
2
|
+
import './results.css';
|
|
3
|
+
export declare function DataQualityPanel({ items, problem }: {
|
|
3
4
|
items: DataQualityItem[];
|
|
4
|
-
|
|
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 {
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
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__*/
|
|
17
|
-
children:
|
|
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("
|
|
20
|
-
|
|
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,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
|
|
4
|
-
export function
|
|
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-
|
|
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
|
-
|
|
34
|
-
className: "xp-
|
|
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-
|
|
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,16 @@
|
|
|
1
|
+
import type { PhaseSummary } from '../../types/endpoints.js';
|
|
2
|
+
import type { ResultsContext } from './results.model.js';
|
|
3
|
+
import type { LegacySnapshot } from './snapshot.js';
|
|
4
|
+
/** Stands in for CORE-15a winnerArm, borrowing the live decision only for the newest rollout. */
|
|
5
|
+
export declare function legacyRolloutLine(snapshot: LegacySnapshot, phase: PhaseSummary, phases: PhaseSummary[], decision?: {
|
|
6
|
+
winnerArm?: string;
|
|
7
|
+
}): string;
|
|
8
|
+
/** Stands in for CORE-15a minExposuresPerArm; absent historical minima keep the old dash. */
|
|
9
|
+
export declare function legacyMinimum(snapshot: LegacySnapshot, ctx: ResultsContext): number | undefined;
|
|
10
|
+
/** Stands in for CORE-15a minExposuresPerArm by deriving the old notice from the frozen verdict. */
|
|
11
|
+
export declare function legacyTooFew(snapshot: LegacySnapshot): boolean;
|
|
12
|
+
/** Stands in for CORE-15a winnerArm in rollout recommendations using the old recommended arm and label. */
|
|
13
|
+
export declare function legacyRecommendationWinner(snapshot: LegacySnapshot, phase?: PhaseSummary): {
|
|
14
|
+
key: string | null;
|
|
15
|
+
label: string;
|
|
16
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RESULTS_COPY, shippingTitle } from '../copy/results.js';
|
|
2
|
+
import { armLabel } from '../labels.js';
|
|
3
|
+
/** Stands in for CORE-15a winnerArm, borrowing the live decision only for the newest rollout. */ export function legacyRolloutLine(snapshot, phase, phases, decision) {
|
|
4
|
+
const newestRollout = phases.filter((phase)=>phase.phaseKind === 'rollout').reduce((latest, phase)=>latest === null || phase.phase > latest ? phase.phase : latest, null);
|
|
5
|
+
const winner = snapshot.winnerArm ?? (snapshot.phase === newestRollout ? decision?.winnerArm : undefined);
|
|
6
|
+
return shippingTitle(winner ? phase.arms.find((arm)=>arm.key === winner)?.label ?? armLabel(winner) : RESULTS_COPY.shippedGroup);
|
|
7
|
+
}
|
|
8
|
+
/** Stands in for CORE-15a minExposuresPerArm; absent historical minima keep the old dash. */ export function legacyMinimum(snapshot, ctx) {
|
|
9
|
+
return snapshot.minExposuresPerArm ?? ctx.minExposuresPerArm;
|
|
10
|
+
}
|
|
11
|
+
/** Stands in for CORE-15a minExposuresPerArm by deriving the old notice from the frozen verdict. */ export function legacyTooFew(snapshot) {
|
|
12
|
+
return snapshot.verdict.code === 'collecting' || snapshot.verdict.code === 'rollout-collecting';
|
|
13
|
+
}
|
|
14
|
+
/** Stands in for CORE-15a winnerArm in rollout recommendations using the old recommended arm and label. */ export function legacyRecommendationWinner(snapshot, phase) {
|
|
15
|
+
const key = snapshot.winnerArm ?? snapshot.verdict.recommendedArm;
|
|
16
|
+
const stored = phase?.arms.find((arm)=>arm.key === key)?.label.trim();
|
|
17
|
+
return {
|
|
18
|
+
key,
|
|
19
|
+
label: stored || (key && [
|
|
20
|
+
'control',
|
|
21
|
+
'variantA',
|
|
22
|
+
'variantB',
|
|
23
|
+
'variantC',
|
|
24
|
+
'holdout'
|
|
25
|
+
].includes(key) ? armLabel(key) : RESULTS_COPY.shippedGroup)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -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); }
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { DocId, Status } from '../../types/contracts.js';
|
|
2
2
|
import type { PhaseSummary, ResultsResponse } from '../../types/endpoints.js';
|
|
3
3
|
import type { Snapshot } from '../../types/snapshot.js';
|
|
4
|
+
import { type DisplaySnapshot } from './snapshot.js';
|
|
4
5
|
type Metric = Snapshot['metrics'][number];
|
|
5
6
|
type Arm = Metric['perArm'][number];
|
|
6
7
|
type Decision = {
|
|
7
8
|
phase: number;
|
|
8
9
|
winnerArm?: string;
|
|
9
10
|
};
|
|
10
|
-
type DisplaySnapshot = Snapshot;
|
|
11
11
|
export declare function defaultRound({ phases, decision, status }: Pick<ResultsResponse, 'phases'> & {
|
|
12
12
|
decision?: Decision | null;
|
|
13
13
|
status: Status;
|
|
@@ -26,8 +26,8 @@ export type VerdictCardModel = {
|
|
|
26
26
|
guardrailLine?: string;
|
|
27
27
|
};
|
|
28
28
|
export declare function verdictCard({ snapshot, decisionSnapshot, isDecidedTestRound, winnerLabel }: {
|
|
29
|
-
snapshot:
|
|
30
|
-
decisionSnapshot?:
|
|
29
|
+
snapshot: DisplaySnapshot;
|
|
30
|
+
decisionSnapshot?: DisplaySnapshot;
|
|
31
31
|
isDecidedTestRound: boolean;
|
|
32
32
|
winnerLabel: string;
|
|
33
33
|
}): VerdictCardModel;
|
|
@@ -66,17 +66,20 @@ 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
|
}
|
|
72
75
|
export declare function armRows({ snapshot, phase, metricId }: {
|
|
73
|
-
snapshot:
|
|
76
|
+
snapshot: DisplaySnapshot;
|
|
74
77
|
phase: PhaseSummary;
|
|
75
78
|
metricId: DocId;
|
|
76
79
|
}): ArmRow[];
|
|
77
|
-
export declare function guardrailChips(snapshot:
|
|
80
|
+
export declare function guardrailChips(snapshot: DisplaySnapshot): {
|
|
78
81
|
name: string;
|
|
79
|
-
status: "
|
|
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;
|
|
@@ -101,5 +105,5 @@ export interface DataQualityItem {
|
|
|
101
105
|
shares?: string[];
|
|
102
106
|
}
|
|
103
107
|
export declare function dataQuality(snapshot: DisplaySnapshot, ctx?: ResultsContext): DataQualityItem[];
|
|
104
|
-
export declare function verdictLabel(snapshot:
|
|
108
|
+
export declare function verdictLabel(snapshot: DisplaySnapshot): string;
|
|
105
109
|
export {};
|