@delmaredigital/payload-experiments 0.2.0-rc.2 → 0.2.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 +15 -0
- package/dist/admin/TestsNavLink.d.ts +1 -0
- package/dist/admin/TestsNavLink.js +1 -0
- package/dist/admin/actions/ConfirmDialog.d.ts +1 -0
- package/dist/admin/actions/ConfirmDialog.js +7 -5
- package/dist/admin/components/ChipsInput.d.ts +12 -0
- package/dist/admin/components/ChipsInput.js +96 -0
- package/dist/admin/components/RootViewMessage.d.ts +5 -0
- package/dist/admin/components/RootViewMessage.js +15 -0
- package/dist/admin/components/chipsInput.css +11 -0
- package/dist/admin/copy/audience.d.ts +4 -0
- package/dist/admin/copy/audience.js +4 -0
- package/dist/admin/copy/goals.d.ts +44 -0
- package/dist/admin/copy/goals.js +46 -0
- package/dist/admin/results/ArmTable.js +2 -1
- package/dist/admin/results/CappedCell.js +2 -1
- package/dist/admin/results/CiChart.js +8 -7
- package/dist/admin/results/DataQualityPanel.js +3 -2
- package/dist/admin/results/VerdictCard.js +3 -2
- package/dist/admin/styles.css +8 -8
- package/dist/admin/styles.d.ts +1 -0
- package/dist/admin/styles.js +1 -0
- package/dist/admin/surface/SurfaceShell.d.ts +1 -0
- package/dist/admin/surface/SurfaceShell.js +1 -0
- package/dist/admin/surface/TestsHome.js +1 -1
- package/dist/admin/surface/TestsSurface.js +10 -1
- package/dist/admin/surface/goals/GoalForm.d.ts +7 -0
- package/dist/admin/surface/goals/GoalForm.js +470 -0
- package/dist/admin/surface/goals/GoalsBreadcrumb.d.ts +5 -0
- package/dist/admin/surface/goals/GoalsBreadcrumb.js +47 -0
- package/dist/admin/surface/goals/GoalsList.d.ts +6 -0
- package/dist/admin/surface/goals/GoalsList.js +135 -0
- package/dist/admin/surface/goals/data.d.ts +3 -0
- package/dist/admin/surface/goals/data.js +24 -0
- package/dist/admin/surface/goals/goals.css +15 -0
- package/dist/admin/surface/goals/goals.model.d.ts +30 -0
- package/dist/admin/surface/goals/goals.model.js +26 -0
- package/dist/admin/surface/newTest/newTest.css +6 -6
- package/dist/admin/surface/readiness/Banner.js +5 -4
- package/dist/admin/surface/results/ResultsBody.js +3 -2
- package/dist/admin/surface/setting/setting.css +11 -11
- package/dist/admin/surface/surface.css +29 -29
- package/dist/admin/surface/test/GoalSection.js +32 -1
- package/dist/admin/surface/test/TargetingSection.js +27 -10
- package/dist/admin/surface/test/VersionsSection.js +6 -5
- package/dist/admin/surface/test/testPage.css +12 -12
- package/dist/admin/targeting/targeting.model.d.ts +6 -1
- package/dist/admin/targeting/targeting.model.js +18 -2
- package/dist/admin/theme.css +42 -0
- package/dist/admin/theme.d.ts +50 -0
- package/dist/admin/theme.js +49 -0
- package/dist/admin/views/ExperimentsRootView.js +18 -18
- package/dist/collections/metricValidation.d.ts +3 -0
- package/dist/collections/metricValidation.js +9 -0
- package/dist/collections/metrics.js +3 -5
- package/dist/endpoints/preflight.js +3 -2
- package/dist/endpoints/previewToken.js +3 -2
- package/dist/endpoints/recompute.js +3 -2
- package/dist/endpoints/results.js +3 -2
- package/dist/endpoints/routeId.d.ts +5 -0
- package/dist/endpoints/routeId.js +13 -0
- package/dist/endpoints/summary.js +32 -21
- package/dist/endpoints/transitions.js +3 -2
- package/dist/plugin.js +2 -2
- package/dist/puck/editor/CreateExperimentDrawer.d.ts +1 -0
- package/dist/puck/editor/CreateExperimentDrawer.js +34 -25
- package/dist/puck/editor/ExperimentSlotEditor.d.ts +1 -0
- package/dist/puck/editor/ExperimentSlotEditor.js +137 -78
- package/dist/puck/editor/copy.d.ts +3 -1
- package/dist/puck/editor/copy.js +3 -1
- package/dist/puck/editor/editor.css +302 -0
- package/dist/types/surface.d.ts +2 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -530,6 +530,21 @@ components: { ExperimentSlot }
|
|
|
530
530
|
components: { ExperimentSlot: ExperimentSlotEditor }
|
|
531
531
|
```
|
|
532
532
|
|
|
533
|
+
Load the editor stylesheet inside the Puck iframe. With Tailwind v4, add the
|
|
534
|
+
package import **after** Tailwind in the CSS that builds your editor iframe
|
|
535
|
+
stylesheet (the stylesheet listed in payload-puck's `editorStylesheets`):
|
|
536
|
+
|
|
537
|
+
```css
|
|
538
|
+
@import "tailwindcss";
|
|
539
|
+
@import "@delmaredigital/payload-experiments/puck/editor.css";
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Alternatively, serve the exported `puck/editor.css` file from a public URL and
|
|
543
|
+
append that URL to payload-puck's `editorStylesheets`, after the host stylesheet.
|
|
544
|
+
The editor CSS includes its own light and dark palette, selected by
|
|
545
|
+
`data-theme="dark"` or the `dark` class on the iframe's `<html>`. The client component's CSS import alone
|
|
546
|
+
does not reach an iframe configured with `syncHostStyles: false`.
|
|
547
|
+
|
|
533
548
|
Resolve the Puck data on the server with `resolveExperimentData` before
|
|
534
549
|
rendering it. The render component shows only the selected group's slot. The
|
|
535
550
|
editor lets you select a block experiment, edit each group's content, copy the
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import '../theme.css';
|
|
4
|
+
import { theme } from '../theme.js';
|
|
3
5
|
import { useEffect, useId, useRef, useState } from 'react';
|
|
4
6
|
import { createPortal } from 'react-dom';
|
|
5
7
|
import { Button, TextInput } from '@payloadcms/ui';
|
|
@@ -24,7 +26,7 @@ export function DialogFrame({ title, onClose, children }) {
|
|
|
24
26
|
position: 'fixed',
|
|
25
27
|
inset: 0,
|
|
26
28
|
zIndex: 1000,
|
|
27
|
-
background:
|
|
29
|
+
background: theme.color.overlay,
|
|
28
30
|
display: 'grid',
|
|
29
31
|
placeItems: 'center'
|
|
30
32
|
},
|
|
@@ -35,14 +37,14 @@ export function DialogFrame({ title, onClose, children }) {
|
|
|
35
37
|
"aria-labelledby": heading,
|
|
36
38
|
tabIndex: -1,
|
|
37
39
|
style: {
|
|
38
|
-
background:
|
|
39
|
-
color:
|
|
40
|
-
border:
|
|
40
|
+
background: theme.color.bg,
|
|
41
|
+
color: theme.color.text,
|
|
42
|
+
border: `1px solid ${theme.color.borderStrong}`,
|
|
41
43
|
padding: '2rem',
|
|
42
44
|
width: 'min(36rem, 90vw)',
|
|
43
45
|
maxHeight: '90vh',
|
|
44
46
|
overflow: 'auto',
|
|
45
|
-
borderRadius:
|
|
47
|
+
borderRadius: theme.radius.small
|
|
46
48
|
},
|
|
47
49
|
onKeyDown: (event)=>{
|
|
48
50
|
if (event.defaultPrevented) return;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import '../theme.css';
|
|
2
|
+
import './chipsInput.css';
|
|
3
|
+
export interface ChipsInputProps {
|
|
4
|
+
value: string[];
|
|
5
|
+
onChange: (value: string[]) => void;
|
|
6
|
+
label: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
id: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function ChipsInput({ value, onChange, label, description, placeholder, disabled, id }: ChipsInputProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useState } from 'react';
|
|
4
|
+
import { AUDIENCE_COPY } from '../copy/audience.js';
|
|
5
|
+
import '../theme.css';
|
|
6
|
+
import './chipsInput.css';
|
|
7
|
+
export function ChipsInput({ value, onChange, label, description, placeholder, disabled = false, id }) {
|
|
8
|
+
const [draft, setDraft] = useState('');
|
|
9
|
+
const input = useRef(null);
|
|
10
|
+
const commit = (text)=>{
|
|
11
|
+
if (disabled) return;
|
|
12
|
+
const next = [
|
|
13
|
+
...new Set([
|
|
14
|
+
...value,
|
|
15
|
+
...text.split(',')
|
|
16
|
+
].map((item)=>item.trim()).filter(Boolean))
|
|
17
|
+
];
|
|
18
|
+
if (next.length !== value.length || next.some((item, index)=>item !== value[index])) onChange(next);
|
|
19
|
+
setDraft('');
|
|
20
|
+
};
|
|
21
|
+
const remove = (index)=>{
|
|
22
|
+
if (disabled) return;
|
|
23
|
+
onChange(value.filter((_, i)=>i !== index));
|
|
24
|
+
input.current?.focus();
|
|
25
|
+
};
|
|
26
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
27
|
+
className: "xp-chips",
|
|
28
|
+
role: "group",
|
|
29
|
+
"aria-labelledby": `${id}-label`,
|
|
30
|
+
"aria-disabled": disabled,
|
|
31
|
+
children: [
|
|
32
|
+
/*#__PURE__*/ _jsx("label", {
|
|
33
|
+
id: `${id}-label`,
|
|
34
|
+
htmlFor: id,
|
|
35
|
+
children: label
|
|
36
|
+
}),
|
|
37
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
38
|
+
className: "xp-chips-control",
|
|
39
|
+
children: [
|
|
40
|
+
value.map((item, index)=>/*#__PURE__*/ _jsxs("span", {
|
|
41
|
+
className: "xp-chips-item",
|
|
42
|
+
children: [
|
|
43
|
+
/*#__PURE__*/ _jsx("span", {
|
|
44
|
+
children: item
|
|
45
|
+
}),
|
|
46
|
+
/*#__PURE__*/ _jsx("button", {
|
|
47
|
+
type: "button",
|
|
48
|
+
disabled: disabled,
|
|
49
|
+
"aria-label": AUDIENCE_COPY.removeValue(item),
|
|
50
|
+
onClick: ()=>remove(index),
|
|
51
|
+
children: AUDIENCE_COPY.removeSymbol
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
}, item)),
|
|
55
|
+
/*#__PURE__*/ _jsx("input", {
|
|
56
|
+
ref: input,
|
|
57
|
+
id: id,
|
|
58
|
+
type: "text",
|
|
59
|
+
value: draft,
|
|
60
|
+
disabled: disabled,
|
|
61
|
+
placeholder: placeholder,
|
|
62
|
+
"aria-describedby": description ? `${id}-description` : undefined,
|
|
63
|
+
onChange: (event)=>setDraft(event.target.value),
|
|
64
|
+
onBlur: ()=>{
|
|
65
|
+
if (draft.trim()) commit(draft);
|
|
66
|
+
},
|
|
67
|
+
onKeyDown: (event)=>{
|
|
68
|
+
if (disabled || event.nativeEvent.isComposing) return;
|
|
69
|
+
if (event.key === 'Enter' || event.key === ',') {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
commit(draft);
|
|
72
|
+
} else if (event.key === 'Tab' && draft.trim()) commit(draft);
|
|
73
|
+
else if (event.key === 'Backspace' && !draft && value.length) {
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
remove(value.length - 1);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
onPaste: (event)=>{
|
|
79
|
+
if (disabled) return;
|
|
80
|
+
const pasted = event.clipboardData.getData('text');
|
|
81
|
+
if (!pasted.includes(',')) return;
|
|
82
|
+
event.preventDefault();
|
|
83
|
+
const start = event.currentTarget.selectionStart ?? draft.length;
|
|
84
|
+
const end = event.currentTarget.selectionEnd ?? start;
|
|
85
|
+
commit(draft.slice(0, start) + pasted + draft.slice(end));
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
]
|
|
89
|
+
}),
|
|
90
|
+
description ? /*#__PURE__*/ _jsx("p", {
|
|
91
|
+
id: `${id}-description`,
|
|
92
|
+
children: description
|
|
93
|
+
}) : null
|
|
94
|
+
]
|
|
95
|
+
});
|
|
96
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import '../theme.css';
|
|
4
|
+
import { theme } from '../theme.js';
|
|
5
|
+
export function RootViewMessage({ children, alert = false }) {
|
|
6
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
7
|
+
role: alert ? 'alert' : undefined,
|
|
8
|
+
style: {
|
|
9
|
+
padding: theme.space[4],
|
|
10
|
+
color: theme.color.text,
|
|
11
|
+
background: theme.color.bg
|
|
12
|
+
},
|
|
13
|
+
children: children
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
.xp-chips { display: grid; gap: var(--xp-space-2); margin-block: var(--xp-space-4); color: var(--xp-text); font-family: var(--xp-font-body); }
|
|
2
|
+
.xp-chips-control { display: flex; align-items: center; flex-wrap: wrap; gap: var(--xp-space-1); padding: var(--xp-space-2); border: 1px solid var(--xp-border-control); border-radius: var(--xp-radius); background: var(--xp-input-bg); }
|
|
3
|
+
.xp-chips-control:focus-within { outline: 2px solid var(--xp-text); outline-offset: 2px; }
|
|
4
|
+
.xp-chips-item { display: inline-flex; align-items: center; gap: var(--xp-space-1); padding-inline-start: var(--xp-space-2); border-radius: var(--xp-radius); background: var(--xp-surface-raised); overflow-wrap: anywhere; max-width: 100%; }
|
|
5
|
+
.xp-chips .xp-chips-item button { padding: var(--xp-space-1) var(--xp-space-2); border: 0; background: transparent; color: var(--xp-text); font: inherit; cursor: pointer; }
|
|
6
|
+
.xp-chips .xp-chips-control input { flex: 1; min-width: 8rem; width: 0; border: 0; padding: var(--xp-space-1); background: transparent; color: var(--xp-text); font: inherit; }
|
|
7
|
+
.xp-chips input:focus { outline: none; }
|
|
8
|
+
.xp-chips button:focus-visible { outline: 2px solid var(--xp-text); outline-offset: 2px; }
|
|
9
|
+
.xp-chips[aria-disabled='true'] { opacity: .5; }
|
|
10
|
+
.xp-chips[aria-disabled='true'] button { cursor: default; }
|
|
11
|
+
.xp-chips p { margin: 0; color: var(--xp-text-muted); font-size: var(--xp-font-size-small); }
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare const AUDIENCE_COPY: {
|
|
2
|
+
readonly listPlaceholder: "Type a value and press Enter";
|
|
3
|
+
readonly listDescription: "Add one value per chip, for example each page path.";
|
|
4
|
+
readonly removeValue: (value: string) => string;
|
|
5
|
+
readonly removeSymbol: "×";
|
|
2
6
|
readonly emptyListNote: "Add at least one value — an empty list can't be saved.";
|
|
3
7
|
};
|
|
4
8
|
export declare const STRING_OP_LABELS: {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export const AUDIENCE_COPY = {
|
|
2
|
+
listPlaceholder: 'Type a value and press Enter',
|
|
3
|
+
listDescription: 'Add one value per chip, for example each page path.',
|
|
4
|
+
removeValue: (value)=>`Remove ${value}`,
|
|
5
|
+
removeSymbol: '×',
|
|
2
6
|
emptyListNote: "Add at least one value — an empty list can't be saved."
|
|
3
7
|
};
|
|
4
8
|
export const STRING_OP_LABELS = {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const GOALS_COPY: {
|
|
2
|
+
readonly title: "Goals";
|
|
3
|
+
readonly newGoal: "New goal";
|
|
4
|
+
readonly name: "Name";
|
|
5
|
+
readonly source: "Measured by";
|
|
6
|
+
readonly directionColumn: "Better when";
|
|
7
|
+
readonly direction: "Better when it goes";
|
|
8
|
+
readonly increase: "Goes up";
|
|
9
|
+
readonly decrease: "Goes down";
|
|
10
|
+
readonly usedBy: "Used by";
|
|
11
|
+
readonly status: "Status";
|
|
12
|
+
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.";
|
|
15
|
+
readonly loading: "Loading goals…";
|
|
16
|
+
readonly loadError: "Couldn't load goals. Try again.";
|
|
17
|
+
readonly retry: "Try again";
|
|
18
|
+
readonly slug: "Short name";
|
|
19
|
+
readonly slugHelp: "A unique short name for this goal.";
|
|
20
|
+
readonly slugLocked: "The short name stays the same once a test uses this goal.";
|
|
21
|
+
readonly chooseSource: "Choose an outcome";
|
|
22
|
+
readonly window: "Count results for (hours)";
|
|
23
|
+
readonly minimum: "Minimum completions before deciding";
|
|
24
|
+
readonly advanced: "Advanced";
|
|
25
|
+
readonly capping: "Limit very large values";
|
|
26
|
+
readonly capType: "Limit by";
|
|
27
|
+
readonly capValue: "Limit value";
|
|
28
|
+
readonly noCap: "No limit";
|
|
29
|
+
readonly percentile: "Based on past amounts";
|
|
30
|
+
readonly absolute: "Fixed amount";
|
|
31
|
+
readonly capHelp: "For past amounts, enter a number such as 0.99 to limit only the largest 1%; or enter a fixed amount.";
|
|
32
|
+
readonly threshold: "Warn when it gets worse by (%)";
|
|
33
|
+
readonly save: "Save";
|
|
34
|
+
readonly saving: "Saving…";
|
|
35
|
+
readonly cancel: "Cancel";
|
|
36
|
+
readonly remove: "Delete";
|
|
37
|
+
readonly thresholdError: "Enter a percentage of zero or more, or leave blank for 5%.";
|
|
38
|
+
readonly deleting: "Deleting…";
|
|
39
|
+
readonly saveError: "Couldn't save the goal. Try again.";
|
|
40
|
+
readonly deleteError: "Couldn't delete the goal. Try again.";
|
|
41
|
+
readonly breadcrumb: "Breadcrumb";
|
|
42
|
+
readonly missing: "This goal could not be found.";
|
|
43
|
+
};
|
|
44
|
+
export declare function goalUsedBy(count: number): string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export const GOALS_COPY = {
|
|
2
|
+
title: 'Goals',
|
|
3
|
+
newGoal: 'New goal',
|
|
4
|
+
name: 'Name',
|
|
5
|
+
source: 'Measured by',
|
|
6
|
+
directionColumn: 'Better when',
|
|
7
|
+
direction: 'Better when it goes',
|
|
8
|
+
increase: 'Goes up',
|
|
9
|
+
decrease: 'Goes down',
|
|
10
|
+
usedBy: 'Used by',
|
|
11
|
+
status: 'Status',
|
|
12
|
+
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.',
|
|
15
|
+
loading: 'Loading goals…',
|
|
16
|
+
loadError: "Couldn't load goals. Try again.",
|
|
17
|
+
retry: 'Try again',
|
|
18
|
+
slug: 'Short name',
|
|
19
|
+
slugHelp: 'A unique short name for this goal.',
|
|
20
|
+
slugLocked: 'The short name stays the same once a test uses this goal.',
|
|
21
|
+
chooseSource: 'Choose an outcome',
|
|
22
|
+
window: 'Count results for (hours)',
|
|
23
|
+
minimum: 'Minimum completions before deciding',
|
|
24
|
+
advanced: 'Advanced',
|
|
25
|
+
capping: 'Limit very large values',
|
|
26
|
+
capType: 'Limit by',
|
|
27
|
+
capValue: 'Limit value',
|
|
28
|
+
noCap: 'No limit',
|
|
29
|
+
percentile: 'Based on past amounts',
|
|
30
|
+
absolute: 'Fixed amount',
|
|
31
|
+
capHelp: 'For past amounts, enter a number such as 0.99 to limit only the largest 1%; or enter a fixed amount.',
|
|
32
|
+
threshold: 'Warn when it gets worse by (%)',
|
|
33
|
+
save: 'Save',
|
|
34
|
+
saving: 'Saving…',
|
|
35
|
+
cancel: 'Cancel',
|
|
36
|
+
remove: 'Delete',
|
|
37
|
+
thresholdError: 'Enter a percentage of zero or more, or leave blank for 5%.',
|
|
38
|
+
deleting: 'Deleting…',
|
|
39
|
+
saveError: "Couldn't save the goal. Try again.",
|
|
40
|
+
deleteError: "Couldn't delete the goal. Try again.",
|
|
41
|
+
breadcrumb: 'Breadcrumb',
|
|
42
|
+
missing: 'This goal could not be found.'
|
|
43
|
+
};
|
|
44
|
+
export function goalUsedBy(count) {
|
|
45
|
+
return `Used by ${count} ${count === 1 ? 'test' : 'tests'}`;
|
|
46
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { theme } from '../theme.js';
|
|
3
4
|
import { RESULTS_COPY } from '../copy/results.js';
|
|
4
5
|
import { CappedCell } from './CappedCell.js';
|
|
5
6
|
export function ArmTable({ rows, caption, method, metricKind }) {
|
|
@@ -10,7 +11,7 @@ export function ArmTable({ rows, caption, method, metricKind }) {
|
|
|
10
11
|
return /*#__PURE__*/ _jsx("div", {
|
|
11
12
|
className: "xp-arm-table",
|
|
12
13
|
style: {
|
|
13
|
-
color:
|
|
14
|
+
color: theme.color.text,
|
|
14
15
|
overflowX: 'auto'
|
|
15
16
|
},
|
|
16
17
|
children: /*#__PURE__*/ _jsxs("table", {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { theme } from '../theme.js';
|
|
3
4
|
export function CappedCell({ model }) {
|
|
4
5
|
return /*#__PURE__*/ _jsxs("div", {
|
|
5
6
|
className: "xp-capped-cell",
|
|
6
7
|
style: {
|
|
7
|
-
color:
|
|
8
|
+
color: theme.color.text
|
|
8
9
|
},
|
|
9
10
|
children: [
|
|
10
11
|
/*#__PURE__*/ _jsx("span", {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { theme } from '../theme.js';
|
|
3
4
|
import { RESULTS_COPY as C, chartSummary, contentChangeTitle } from '../copy/results.js';
|
|
4
5
|
import { chartModel } from './chart.model.js';
|
|
5
6
|
import { formatPercent } from './format.js';
|
|
6
7
|
const colors = [
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
theme.color.textStrong,
|
|
9
|
+
theme.color.textMuted,
|
|
10
|
+
theme.color.borderAccent
|
|
10
11
|
];
|
|
11
12
|
const date = (t)=>new Intl.DateTimeFormat('en-US', {
|
|
12
13
|
dateStyle: 'medium',
|
|
@@ -28,7 +29,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
|
|
|
28
29
|
return /*#__PURE__*/ _jsxs("section", {
|
|
29
30
|
className: "xp-ci-chart",
|
|
30
31
|
style: {
|
|
31
|
-
color:
|
|
32
|
+
color: theme.color.text
|
|
32
33
|
},
|
|
33
34
|
children: [
|
|
34
35
|
/*#__PURE__*/ _jsx("h2", {
|
|
@@ -50,7 +51,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
|
|
|
50
51
|
x2: 680,
|
|
51
52
|
y1: y(0),
|
|
52
53
|
y2: y(0),
|
|
53
|
-
stroke:
|
|
54
|
+
stroke: theme.color.accent,
|
|
54
55
|
strokeDasharray: "4 4"
|
|
55
56
|
}),
|
|
56
57
|
[
|
|
@@ -146,7 +147,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
|
|
|
146
147
|
x2: x(marker.t),
|
|
147
148
|
y1: 20,
|
|
148
149
|
y2: 230,
|
|
149
|
-
stroke:
|
|
150
|
+
stroke: theme.color.text,
|
|
150
151
|
strokeDasharray: "2 4"
|
|
151
152
|
})
|
|
152
153
|
]
|
|
@@ -156,7 +157,7 @@ export function CiChart({ series, metricId, metricName, phase, contentChanges })
|
|
|
156
157
|
/*#__PURE__*/ _jsx("ul", {
|
|
157
158
|
children: model.variants.map((variant, index)=>/*#__PURE__*/ _jsxs("li", {
|
|
158
159
|
style: {
|
|
159
|
-
color:
|
|
160
|
+
color: theme.color.text
|
|
160
161
|
},
|
|
161
162
|
children: [
|
|
162
163
|
/*#__PURE__*/ _jsx("span", {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { theme } from '../theme.js';
|
|
3
4
|
import { RESULTS_COPY } from '../copy/results.js';
|
|
4
5
|
export function DataQualityPanel({ items }) {
|
|
5
6
|
if (items.length === 0) return null;
|
|
@@ -7,8 +8,8 @@ export function DataQualityPanel({ items }) {
|
|
|
7
8
|
className: "xp-data-quality",
|
|
8
9
|
"aria-label": RESULTS_COPY.quality,
|
|
9
10
|
style: {
|
|
10
|
-
color:
|
|
11
|
-
background:
|
|
11
|
+
color: theme.color.text,
|
|
12
|
+
background: theme.color.surface,
|
|
12
13
|
padding: '1rem'
|
|
13
14
|
},
|
|
14
15
|
children: [
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { theme } from '../theme.js';
|
|
3
4
|
export function VerdictCard({ model, guardrails = [], power, collecting, sinceShipping }) {
|
|
4
5
|
return /*#__PURE__*/ _jsxs("section", {
|
|
5
6
|
className: "xp-verdict-card",
|
|
6
7
|
style: {
|
|
7
|
-
color:
|
|
8
|
-
background:
|
|
8
|
+
color: theme.color.text,
|
|
9
|
+
background: theme.color.surface,
|
|
9
10
|
padding: '1rem'
|
|
10
11
|
},
|
|
11
12
|
children: [
|
package/dist/admin/styles.css
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* Admin styles for the experiments plugin; loaded by src/admin/styles.ts. */
|
|
2
2
|
.xp-status-pill { font-weight: 600; }
|
|
3
|
-
.xp-status-pill--neutral { background: var(--
|
|
4
|
-
.xp-status-pill--success { background: var(--
|
|
5
|
-
.xp-status-pill--warning { background: var(--
|
|
6
|
-
.xp-status-pill--info { background: var(--
|
|
7
|
-
.xp-status-pill--muted { background: var(--
|
|
8
|
-
.xp-locked-notice, .xp-notice { padding: 0.75rem; border-inline-start: 3px solid var(--
|
|
9
|
-
.xp-notice--warning { border-color: var(--
|
|
10
|
-
.xp-notice--error { border-color: var(--
|
|
3
|
+
.xp-status-pill--neutral { background: var(--xp-border); color: var(--xp-text-strong); }
|
|
4
|
+
.xp-status-pill--success { background: var(--xp-success-bg); color: var(--xp-success-text-strong); }
|
|
5
|
+
.xp-status-pill--warning { background: var(--xp-warning-bg); color: var(--xp-warning-text-strong); }
|
|
6
|
+
.xp-status-pill--info { background: var(--xp-border-strong); color: var(--xp-text-emphasis); }
|
|
7
|
+
.xp-status-pill--muted { background: var(--xp-surface-raised); color: var(--xp-text-muted); }
|
|
8
|
+
.xp-locked-notice, .xp-notice { padding: 0.75rem; border-inline-start: 3px solid var(--xp-border-accent); background: var(--xp-surface); color: var(--xp-text-strong); }
|
|
9
|
+
.xp-notice--warning { border-color: var(--xp-warning); background: var(--xp-warning-surface); }
|
|
10
|
+
.xp-notice--error { border-color: var(--xp-error); background: var(--xp-error-surface); }
|
package/dist/admin/styles.d.ts
CHANGED
package/dist/admin/styles.js
CHANGED
|
@@ -4,6 +4,8 @@ import { NewTest } from './newTest/NewTest.js';
|
|
|
4
4
|
import { TestPage } from './test/TestPage.js';
|
|
5
5
|
import { ResultsRoute } from './ResultsRoute.js';
|
|
6
6
|
import { SurfaceShell } from './SurfaceShell.js';
|
|
7
|
+
import { GoalForm } from './goals/GoalForm.js';
|
|
8
|
+
import { GoalsList } from './goals/GoalsList.js';
|
|
7
9
|
import { TestsHome } from './TestsHome.js';
|
|
8
10
|
export function TestsSurface(props) {
|
|
9
11
|
const surface = {
|
|
@@ -22,7 +24,14 @@ export function TestsSurface(props) {
|
|
|
22
24
|
children: props.route === 'home' ? /*#__PURE__*/ _jsx(TestsHome, {
|
|
23
25
|
adminRoute: props.adminRoute,
|
|
24
26
|
apiRoute: props.apiRoute
|
|
25
|
-
}) : props.route === '
|
|
27
|
+
}) : props.route === 'goals' ? /*#__PURE__*/ _jsx(GoalsList, {
|
|
28
|
+
surface: surface,
|
|
29
|
+
returnToTest: props.returnToTest
|
|
30
|
+
}) : props.route === 'goalNew' || props.route === 'goal' ? /*#__PURE__*/ _jsx(GoalForm, {
|
|
31
|
+
surface: surface,
|
|
32
|
+
id: props.route === 'goal' ? props.id : undefined,
|
|
33
|
+
returnToTest: props.returnToTest
|
|
34
|
+
}, props.route === 'goalNew' ? 'new' : props.id) : props.route === 'new' ? /*#__PURE__*/ _jsx(NewTest, {
|
|
26
35
|
surface: surface,
|
|
27
36
|
pages: props.pages
|
|
28
37
|
}) : props.id === undefined ? null : props.route === 'test' ? /*#__PURE__*/ _jsx(TestPage, {
|