@delmaredigital/payload-experiments 0.4.0-rc.1 → 0.4.0-rc.3
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 +283 -773
- package/dist/admin/TestsDashboardCards.d.ts +1 -0
- package/dist/admin/TestsDashboardCards.js +4 -8
- package/dist/admin/TestsNavLink.d.ts +1 -0
- package/dist/admin/TestsNavLink.js +4 -10
- package/dist/admin/api.d.ts +7 -0
- package/dist/admin/api.js +27 -0
- package/dist/admin/blocks/BlockPanel.js +65 -19
- package/dist/admin/blocks/formApi.d.ts +3 -0
- package/dist/admin/blocks/formApi.js +9 -3
- package/dist/admin/blocks/statusCache.d.ts +2 -0
- package/dist/admin/blocks/statusCache.js +11 -2
- package/dist/admin/copy/blocks.d.ts +16 -0
- package/dist/admin/copy/blocks.js +27 -1
- package/dist/admin/copy/common.d.ts +1 -0
- package/dist/admin/copy/common.js +1 -1
- package/dist/admin/copy/goals.d.ts +1 -0
- package/dist/admin/copy/goals.js +1 -0
- package/dist/admin/copy/pages.d.ts +2 -4
- package/dist/admin/copy/pages.js +3 -5
- package/dist/admin/copy/readiness.d.ts +1 -0
- package/dist/admin/copy/readiness.js +1 -0
- package/dist/admin/goals/XpGoalField.d.ts +2 -0
- package/dist/admin/goals/XpGoalField.js +51 -35
- package/dist/admin/goals/xpGoalField.css +48 -0
- package/dist/admin/paths.d.ts +3 -0
- package/dist/admin/paths.js +3 -0
- package/dist/admin/surface/TestsHome.js +2 -4
- package/dist/admin/surface/TestsSurface.js +2 -5
- package/dist/admin/surface/goals/GoalForm.js +18 -18
- package/dist/admin/surface/goals/GoalsList.js +2 -1
- package/dist/admin/surface/home.model.d.ts +2 -2
- package/dist/admin/surface/newTest/NewTest.js +2 -4
- package/dist/admin/surface/newTest/PageWizard.js +7 -2
- package/dist/admin/surface/pagePicker/CopyRoute.d.ts +1 -1
- package/dist/admin/surface/pagePicker/{PagePicker.d.ts → PageCombobox.d.ts} +3 -3
- package/dist/admin/surface/pagePicker/PageCombobox.js +395 -0
- package/dist/admin/surface/pagePicker/pagePicker.css +10 -0
- package/dist/admin/surface/pagePicker/pagePicker.model.d.ts +2 -0
- package/dist/admin/surface/readiness/readiness.model.js +1 -0
- package/dist/admin/surface/results/ResultsHeader.js +3 -8
- package/dist/admin/surface/results/useResults.d.ts +10 -0
- package/dist/admin/surface/test/GoalSection.js +4 -7
- package/dist/admin/surface/test/Section.js +9 -8
- package/dist/admin/surface/test/TestPage.js +3 -8
- package/dist/admin/surface/test/pageParts.js +10 -39
- package/dist/admin/surface/test/testPage.css +0 -5
- package/dist/admin/surface/useTestDocument.d.ts +4 -0
- package/dist/admin/surfaceUrls.d.ts +7 -0
- package/dist/admin/surfaceUrls.js +19 -0
- package/dist/admin/theme.css +2 -0
- package/dist/admin/useApi.d.ts +10 -0
- package/dist/admin/views/CollectionListRedirect.d.ts +1 -0
- package/dist/admin/views/CollectionListRedirect.js +1 -1
- package/dist/admin/views/ExperimentsRootView.js +18 -165
- package/dist/admin/views/GoalEditRedirect.d.ts +4 -0
- package/dist/admin/views/GoalEditRedirect.js +14 -0
- package/dist/admin/views/GoalsCollectionListView.d.ts +2 -0
- package/dist/admin/views/GoalsCollectionListView.js +4 -0
- package/dist/admin/views/TestsCollectionListView.d.ts +2 -0
- package/dist/admin/views/TestsCollectionListView.js +4 -0
- package/dist/admin/views/TestsNavLinkServer.d.ts +1 -0
- package/dist/admin/views/TestsNavLinkServer.js +1 -1
- package/dist/admin/views/buildSurfaceProps.d.ts +8 -0
- package/dist/admin/views/buildSurfaceProps.js +143 -0
- package/dist/admin/views/renderCollectionList.d.ts +2 -0
- package/dist/admin/views/renderCollectionList.js +34 -0
- package/dist/admin/views/renderTestsSurface.d.ts +3 -0
- package/dist/admin/views/renderTestsSurface.js +34 -0
- package/dist/collections/experiments/config.js +9 -5
- package/dist/collections/metrics.js +16 -4
- package/dist/exports/adminRsc.d.ts +3 -0
- package/dist/exports/adminRsc.js +3 -0
- package/dist/fields/xpGoal.js +2 -14
- package/dist/goals/picker/copy.d.ts +2 -0
- package/dist/goals/picker/copy.js +7 -0
- package/dist/goals/validate.d.ts +3 -0
- package/dist/goals/validate.js +15 -0
- package/dist/hooks/puckGoals.d.ts +5 -0
- package/dist/hooks/puckGoals.js +62 -0
- package/dist/plugin.js +12 -18
- package/dist/puck/editor/editor.chrome.css +13 -0
- package/dist/puck/editor/editor.css +105 -0
- package/dist/puck/editor/xpGoalPuckEditorField.js +28 -20
- package/dist/sanitizeReadinessDetail.js +2 -0
- package/dist/transitions/checkStart.d.ts +2 -1
- package/dist/transitions/checkStart.js +3 -1
- package/dist/transitions/decide.js +1 -0
- package/dist/transitions/start.js +2 -1
- package/dist/types/endpoints.d.ts +1 -1
- package/dist/ui/ui.css +4 -0
- package/package.json +1 -1
- package/dist/admin/surface/pagePicker/PagePicker.js +0 -172
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { Button, FieldError, FieldLabel, TextInput, useAuth, useConfig, useField } from '@payloadcms/ui';
|
|
3
|
+
import { Button, FieldError, FieldLabel, SelectInput, TextInput, useAuth, useConfig, useField } from '@payloadcms/ui';
|
|
4
4
|
import { useId } from 'react';
|
|
5
5
|
import { useClickGoalPicker } from '../../goals/picker/useClickGoalPicker.js';
|
|
6
6
|
import { CLICK_GOAL_COPY as C } from '../../goals/picker/copy.js';
|
|
7
|
+
import '../theme.css';
|
|
8
|
+
import './xpGoalField.css';
|
|
7
9
|
export function XpGoalField({ path, field, readOnly }) {
|
|
8
10
|
const { value, setValue, showError } = useField({
|
|
9
11
|
path
|
|
@@ -24,6 +26,7 @@ export function XpGoalField({ path, field, readOnly }) {
|
|
|
24
26
|
}
|
|
25
27
|
};
|
|
26
28
|
return /*#__PURE__*/ _jsxs("div", {
|
|
29
|
+
className: "field-type xp-goal-field",
|
|
27
30
|
children: [
|
|
28
31
|
/*#__PURE__*/ _jsx(TextInput, {
|
|
29
32
|
path: path,
|
|
@@ -43,36 +46,40 @@ export function XpGoalField({ path, field, readOnly }) {
|
|
|
43
46
|
}),
|
|
44
47
|
picker.canManage && !locked ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
45
48
|
children: [
|
|
46
|
-
/*#__PURE__*/
|
|
47
|
-
|
|
48
|
-
children: C.choose
|
|
49
|
-
}),
|
|
50
|
-
/*#__PURE__*/ _jsxs("select", {
|
|
51
|
-
id: `${id}-picker`,
|
|
52
|
-
value: picker.goals.some((goal)=>goal.slug === value) ? value : '',
|
|
53
|
-
onChange: (event)=>{
|
|
54
|
-
if (event.currentTarget.value) setValue(event.currentTarget.value);
|
|
55
|
-
},
|
|
49
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
50
|
+
className: "xp-goal-field__row",
|
|
56
51
|
children: [
|
|
57
|
-
/*#__PURE__*/ _jsx(
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
/*#__PURE__*/ _jsx(SelectInput, {
|
|
53
|
+
name: `${path}__xpGoalPicker`,
|
|
54
|
+
path: `${path}__xpGoalPicker`,
|
|
55
|
+
className: "xp-goal-field__select",
|
|
56
|
+
value: picker.goals.some((goal)=>goal.slug === value) ? value : undefined,
|
|
57
|
+
options: picker.goals.map((goal)=>({
|
|
58
|
+
value: goal.slug,
|
|
59
|
+
label: goal.name
|
|
60
|
+
})),
|
|
61
|
+
placeholder: C.choose,
|
|
62
|
+
isClearable: false,
|
|
63
|
+
label: C.choose,
|
|
64
|
+
onChange: (option)=>{
|
|
65
|
+
if (option && !Array.isArray(option)) setValue(String(option.value));
|
|
66
|
+
}
|
|
60
67
|
}),
|
|
61
|
-
picker.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
!picker.panel.open ? /*#__PURE__*/ _jsx(Button, {
|
|
69
|
+
type: "button",
|
|
70
|
+
margin: false,
|
|
71
|
+
buttonStyle: "secondary",
|
|
72
|
+
onClick: picker.open,
|
|
73
|
+
children: C.newGoal
|
|
74
|
+
}) : null
|
|
65
75
|
]
|
|
66
76
|
}),
|
|
67
77
|
picker.undefinedKey(value ?? '') ? /*#__PURE__*/ _jsx("p", {
|
|
68
78
|
role: "status",
|
|
69
79
|
children: C.undefinedKey
|
|
70
80
|
}) : null,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
onClick: picker.open,
|
|
74
|
-
children: C.newGoal
|
|
75
|
-
}) : /*#__PURE__*/ _jsxs("section", {
|
|
81
|
+
picker.panel.open ? /*#__PURE__*/ _jsxs("section", {
|
|
82
|
+
className: "xp-goal-field__panel",
|
|
76
83
|
"aria-labelledby": `${id}-title`,
|
|
77
84
|
children: [
|
|
78
85
|
/*#__PURE__*/ _jsx("h3", {
|
|
@@ -131,20 +138,29 @@ export function XpGoalField({ path, field, readOnly }) {
|
|
|
131
138
|
role: "alert",
|
|
132
139
|
children: picker.panel.errors.general
|
|
133
140
|
}) : null,
|
|
134
|
-
/*#__PURE__*/
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
142
|
+
className: "xp-goal-field__actions",
|
|
143
|
+
children: [
|
|
144
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
145
|
+
type: "button",
|
|
146
|
+
margin: false,
|
|
147
|
+
buttonStyle: "primary",
|
|
148
|
+
disabled: picker.panel.pending || !picker.panel.name.trim(),
|
|
149
|
+
onClick: ()=>void picker.create(),
|
|
150
|
+
children: C.createGoal
|
|
151
|
+
}),
|
|
152
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
153
|
+
type: "button",
|
|
154
|
+
margin: false,
|
|
155
|
+
buttonStyle: "secondary",
|
|
156
|
+
disabled: picker.panel.pending,
|
|
157
|
+
onClick: picker.cancel,
|
|
158
|
+
children: C.cancel
|
|
159
|
+
})
|
|
160
|
+
]
|
|
145
161
|
})
|
|
146
162
|
]
|
|
147
|
-
})
|
|
163
|
+
}) : null
|
|
148
164
|
]
|
|
149
165
|
}) : null
|
|
150
166
|
]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
.xp-goal-field {
|
|
2
|
+
display: grid;
|
|
3
|
+
gap: var(--xp-field-gap);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.xp-goal-field__row {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-wrap: wrap;
|
|
9
|
+
align-items: end;
|
|
10
|
+
gap: var(--xp-space-2);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.xp-goal-field__select {
|
|
14
|
+
flex: 1 1 auto;
|
|
15
|
+
min-width: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.xp-goal-field__panel {
|
|
19
|
+
display: grid;
|
|
20
|
+
gap: var(--xp-field-gap);
|
|
21
|
+
border: 1px solid var(--xp-border);
|
|
22
|
+
border-radius: var(--xp-radius-control);
|
|
23
|
+
padding: var(--xp-space-4);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.xp-goal-field > p,
|
|
27
|
+
.xp-goal-field__panel > h3,
|
|
28
|
+
.xp-goal-field__panel > p {
|
|
29
|
+
margin: 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.xp-goal-field__panel details[open] > summary {
|
|
33
|
+
margin-bottom: var(--xp-field-gap);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.xp-goal-field__actions {
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-wrap: wrap;
|
|
39
|
+
gap: var(--xp-space-2);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Payload halves the gap between fields below 768px; match it inside the field. */
|
|
43
|
+
@media (max-width: 768px) {
|
|
44
|
+
.xp-goal-field,
|
|
45
|
+
.xp-goal-field__panel {
|
|
46
|
+
gap: calc(var(--xp-field-gap) / 2);
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/admin/paths.d.ts
CHANGED
|
@@ -14,3 +14,6 @@ export declare const XP_BLOCK_STATUS = "@delmaredigital/payload-experiments/admi
|
|
|
14
14
|
export declare const XP_BLOCK_ROW_LABEL = "@delmaredigital/payload-experiments/admin/client#BlockSlotRowLabel";
|
|
15
15
|
export declare const XP_COPY_ORIGINAL = "@delmaredigital/payload-experiments/admin/client#CopyOriginalField";
|
|
16
16
|
export declare const XP_GOAL_FIELD = "@delmaredigital/payload-experiments/admin/client#XpGoalField";
|
|
17
|
+
export declare const XP_TESTS_COLLECTION_LIST = "@delmaredigital/payload-experiments/admin/rsc#TestsCollectionListView";
|
|
18
|
+
export declare const XP_GOALS_COLLECTION_LIST = "@delmaredigital/payload-experiments/admin/rsc#GoalsCollectionListView";
|
|
19
|
+
export declare const XP_GOAL_EDIT_REDIRECT = "@delmaredigital/payload-experiments/admin/rsc#GoalEditRedirect";
|
package/dist/admin/paths.js
CHANGED
|
@@ -14,3 +14,6 @@ export const XP_BLOCK_STATUS = '@delmaredigital/payload-experiments/admin/client
|
|
|
14
14
|
export const XP_BLOCK_ROW_LABEL = '@delmaredigital/payload-experiments/admin/client#BlockSlotRowLabel';
|
|
15
15
|
export const XP_COPY_ORIGINAL = '@delmaredigital/payload-experiments/admin/client#CopyOriginalField';
|
|
16
16
|
export const XP_GOAL_FIELD = '@delmaredigital/payload-experiments/admin/client#XpGoalField';
|
|
17
|
+
export const XP_TESTS_COLLECTION_LIST = '@delmaredigital/payload-experiments/admin/rsc#TestsCollectionListView';
|
|
18
|
+
export const XP_GOALS_COLLECTION_LIST = '@delmaredigital/payload-experiments/admin/rsc#GoalsCollectionListView';
|
|
19
|
+
export const XP_GOAL_EDIT_REDIRECT = '@delmaredigital/payload-experiments/admin/rsc#GoalEditRedirect';
|
|
@@ -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 { surfaceUrls } from '../surfaceUrls.js';
|
|
3
4
|
import { useEffect, useMemo, useState } from 'react';
|
|
4
5
|
import { formatAdminURL } from 'payload/shared';
|
|
5
6
|
import { fetchAllDocs } from '../../lib/fetchAllDocs.js';
|
|
@@ -154,10 +155,7 @@ export function TestsHome({ adminRoute, apiRoute, canManage = false, crumbs, fla
|
|
|
154
155
|
]
|
|
155
156
|
}),
|
|
156
157
|
canManage ? /*#__PURE__*/ _jsx(Button, {
|
|
157
|
-
href:
|
|
158
|
-
adminRoute,
|
|
159
|
-
path: '/experiments/goals'
|
|
160
|
-
}),
|
|
158
|
+
href: surfaceUrls.goals(adminRoute),
|
|
161
159
|
children: SURFACE_COPY.goals
|
|
162
160
|
}) : null,
|
|
163
161
|
newTest
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { surfaceUrls } from '../surfaceUrls.js';
|
|
3
4
|
import { useState } from 'react';
|
|
4
|
-
import { formatAdminURL } from 'payload/shared';
|
|
5
5
|
import { SURFACE_COPY } from '../copy/surface.js';
|
|
6
6
|
import { NewTest } from './newTest/NewTest.js';
|
|
7
7
|
import { TestPage } from './test/TestPage.js';
|
|
@@ -40,10 +40,7 @@ function SurfacePage(props) {
|
|
|
40
40
|
}
|
|
41
41
|
];
|
|
42
42
|
if (props.route !== 'home') {
|
|
43
|
-
crumbs[0].href =
|
|
44
|
-
adminRoute: props.adminRoute,
|
|
45
|
-
path: '/experiments'
|
|
46
|
-
});
|
|
43
|
+
crumbs[0].href = props.canManage ? surfaceUrls.home(props.adminRoute) : undefined;
|
|
47
44
|
crumbs.push({
|
|
48
45
|
label: props.route === 'new' ? SURFACE_COPY.newTest : props.route === 'results' ? SURFACE_COPY.resultsTitle : SURFACE_COPY.test
|
|
49
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 { surfaceUrls } from '../../surfaceUrls.js';
|
|
3
4
|
import { useEffect, useRef, useState } from 'react';
|
|
4
5
|
import { useRouter } from 'next/navigation.js';
|
|
5
6
|
import { formatAdminURL } from 'payload/shared';
|
|
@@ -50,24 +51,16 @@ export function GoalForm({ surface, id, returnToTest }) {
|
|
|
50
51
|
const [loadError, setLoadError] = useState('');
|
|
51
52
|
const [error, setError] = useState('');
|
|
52
53
|
const [fieldErrors, setFieldErrors] = useState({});
|
|
54
|
+
const [seenFieldErrors, setSeenFieldErrors] = useState(fieldErrors);
|
|
55
|
+
const [advancedOpen, setAdvancedOpen] = useState(false);
|
|
53
56
|
const [pending, setPending] = useState(null);
|
|
54
57
|
const [slugEdited, setSlugEdited] = useState(false);
|
|
55
58
|
const [attempt, setAttempt] = useState(0);
|
|
56
59
|
const inFlight = useRef(false);
|
|
57
|
-
const advanced = useRef(null);
|
|
58
60
|
const [confirmDelete, setConfirmDelete] = useState(false);
|
|
59
|
-
|
|
60
|
-
if (advanced.current && (fieldErrors.slug || fieldErrors.capType || fieldErrors.capValue || fieldErrors.warningPercent)) advanced.current.open = true;
|
|
61
|
-
}, [
|
|
62
|
-
fieldErrors
|
|
63
|
-
]);
|
|
64
|
-
const returnQuery = returnToTest ? `?${new URLSearchParams({
|
|
61
|
+
const listUrl = surfaceUrls.goals(surface.adminRoute, returnToTest ? {
|
|
65
62
|
return: returnToTest
|
|
66
|
-
}
|
|
67
|
-
const listUrl = formatAdminURL({
|
|
68
|
-
adminRoute: surface.adminRoute,
|
|
69
|
-
path: `/experiments/goals${returnQuery}`
|
|
70
|
-
});
|
|
63
|
+
} : undefined);
|
|
71
64
|
useEffect(()=>{
|
|
72
65
|
const controller = new AbortController();
|
|
73
66
|
setReady(false);
|
|
@@ -111,6 +104,11 @@ export function GoalForm({ surface, id, returnToTest }) {
|
|
|
111
104
|
]);
|
|
112
105
|
const source = sourceFor(draft.source, surface.metricSources);
|
|
113
106
|
const click = draft.source.startsWith('click:');
|
|
107
|
+
// Keep the disclosure and its new field errors in the same commit.
|
|
108
|
+
if (fieldErrors !== seenFieldErrors) {
|
|
109
|
+
setSeenFieldErrors(fieldErrors);
|
|
110
|
+
if (click && fieldErrors.slug || fieldErrors.capType || fieldErrors.capValue || fieldErrors.warningPercent) setAdvancedOpen(true);
|
|
111
|
+
}
|
|
114
112
|
const hint = metricSourceHint(source);
|
|
115
113
|
const options = metricSourceOptions(surface.metricSources);
|
|
116
114
|
const set = (key, value)=>setDraft((current)=>({
|
|
@@ -180,7 +178,7 @@ export function GoalForm({ surface, id, returnToTest }) {
|
|
|
180
178
|
if (cause instanceof GoalResponseError) setFieldErrors(Object.fromEntries(Object.entries(cause.fields).flatMap(([path, message])=>fieldNames[path] ? [
|
|
181
179
|
[
|
|
182
180
|
fieldNames[path],
|
|
183
|
-
path === 'slug' ? C.duplicateSlug : message
|
|
181
|
+
path === 'slug' ? click ? C.duplicateSlug : C.duplicateSlugMain : message
|
|
184
182
|
]
|
|
185
183
|
] : [])));
|
|
186
184
|
inFlight.current = false;
|
|
@@ -215,10 +213,7 @@ export function GoalForm({ surface, id, returnToTest }) {
|
|
|
215
213
|
crumbs: [
|
|
216
214
|
{
|
|
217
215
|
label: SURFACE_COPY.title,
|
|
218
|
-
href:
|
|
219
|
-
adminRoute: surface.adminRoute,
|
|
220
|
-
path: '/experiments'
|
|
221
|
-
})
|
|
216
|
+
href: surfaceUrls.home(surface.adminRoute)
|
|
222
217
|
},
|
|
223
218
|
{
|
|
224
219
|
label: C.title,
|
|
@@ -326,6 +321,10 @@ export function GoalForm({ surface, id, returnToTest }) {
|
|
|
326
321
|
...current,
|
|
327
322
|
slug: clickGoalSlug(draft.name) ? undefined : C.slugRule
|
|
328
323
|
}));
|
|
324
|
+
else if (sourceId === 'click:' !== click) setFieldErrors((current)=>({
|
|
325
|
+
...current,
|
|
326
|
+
slug: undefined
|
|
327
|
+
}));
|
|
329
328
|
},
|
|
330
329
|
children: [
|
|
331
330
|
/*#__PURE__*/ _jsx("option", {
|
|
@@ -381,7 +380,8 @@ export function GoalForm({ surface, id, returnToTest }) {
|
|
|
381
380
|
}),
|
|
382
381
|
/*#__PURE__*/ _jsxs("details", {
|
|
383
382
|
className: "xp-goal-advanced",
|
|
384
|
-
|
|
383
|
+
open: advancedOpen,
|
|
384
|
+
onToggle: (event)=>setAdvancedOpen(event.currentTarget.open),
|
|
385
385
|
children: [
|
|
386
386
|
/*#__PURE__*/ _jsx("summary", {
|
|
387
387
|
children: C.advanced
|
|
@@ -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 { surfaceUrls } from '../../surfaceUrls.js';
|
|
3
4
|
import { sourceFor } from '../../metricSource.model.js';
|
|
4
5
|
import { useEffect, useState } from 'react';
|
|
5
6
|
import { formatAdminURL } from 'payload/shared';
|
|
@@ -60,7 +61,7 @@ export function GoalsList({ surface, returnToTest }) {
|
|
|
60
61
|
crumbs: [
|
|
61
62
|
{
|
|
62
63
|
label: SURFACE_COPY.title,
|
|
63
|
-
href:
|
|
64
|
+
href: surfaceUrls.home(surface.adminRoute)
|
|
64
65
|
},
|
|
65
66
|
{
|
|
66
67
|
label: C.title
|
|
@@ -23,11 +23,11 @@ type Summary = SummaryResponse[DocId] | undefined;
|
|
|
23
23
|
export type Health = 'red' | 'amber' | 'green';
|
|
24
24
|
export declare function healthDot(test: HomeTest, summary: Summary): Health | undefined;
|
|
25
25
|
export declare function groupTests(tests: readonly HomeTest[], summaries: SummaryResponse, search?: string): {
|
|
26
|
-
label: "Needs attention" | "Running" | "Decided" | "
|
|
26
|
+
label: "Needs attention" | "Running" | "Decided" | "Ready to start" | "Draft" | "Archived";
|
|
27
27
|
tests: HomeTest[];
|
|
28
28
|
}[];
|
|
29
29
|
export declare function homeCard(test: HomeTest, summary: Summary, adminRoute: string, flagPoints?: ReadinessContext['flagPoints'], goalNames?: Readonly<Record<string, string>>): {
|
|
30
|
-
kind: "
|
|
30
|
+
kind: "Page block" | "Setting" | "Whole page";
|
|
31
31
|
pill: {
|
|
32
32
|
label: string;
|
|
33
33
|
tone: import("../status.model.js").PillTone;
|
|
@@ -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 { surfaceUrls } from '../../surfaceUrls.js';
|
|
3
4
|
import { fetchAllDocs } from '../../../lib/fetchAllDocs.js';
|
|
4
5
|
import { useEffect, useRef, useState } from 'react';
|
|
5
6
|
import { useRouter } from 'next/navigation.js';
|
|
@@ -372,10 +373,7 @@ export function NewTest({ surface, pages }) {
|
|
|
372
373
|
type: "button",
|
|
373
374
|
disabled: pending,
|
|
374
375
|
onClick: ()=>{
|
|
375
|
-
if (step === 'kind') router.push(
|
|
376
|
-
adminRoute: surface.adminRoute,
|
|
377
|
-
path: '/experiments'
|
|
378
|
-
}));
|
|
376
|
+
if (step === 'kind') router.push(surfaceUrls.home(surface.adminRoute));
|
|
379
377
|
else {
|
|
380
378
|
setError('');
|
|
381
379
|
setStep(step === 'name' && kind === 'flag' ? 'setting' : 'kind');
|
|
@@ -5,7 +5,7 @@ import { useRouter } from 'next/navigation.js';
|
|
|
5
5
|
import { formatAdminURL } from 'payload/shared';
|
|
6
6
|
import { useTestDocument } from '../useTestDocument.js';
|
|
7
7
|
import { CopyRoute } from '../pagePicker/CopyRoute.js';
|
|
8
|
-
import {
|
|
8
|
+
import { PageCombobox } from '../pagePicker/PageCombobox.js';
|
|
9
9
|
import { testPageCollection, controlFirst } from '../pagePicker/pagePicker.model.js';
|
|
10
10
|
import { NEW_TEST_COPY as C } from '../../copy/newTest.js';
|
|
11
11
|
import { READINESS_COPY } from '../../copy/readiness.js';
|
|
@@ -13,6 +13,7 @@ import { TEST_PAGE } from '../../copy/testPage.js';
|
|
|
13
13
|
import { SURFACE_COPY } from '../../copy/surface.js';
|
|
14
14
|
import { pageStepCopy } from '../../copy/pages.js';
|
|
15
15
|
import { READINESS, nextStep, pageReadinessContext, readinessArm } from '../readiness/readiness.model.js';
|
|
16
|
+
import { FieldErrors } from '../test/fields.js';
|
|
16
17
|
import { SaveStatus } from '../readiness/SaveStatus.js';
|
|
17
18
|
import { createApi } from '../../api.js';
|
|
18
19
|
import { useTransition } from '../readiness/useTransition.js';
|
|
@@ -77,7 +78,7 @@ import { useTransition } from '../readiness/useTransition.js';
|
|
|
77
78
|
if (section === 'versions') setStep(key ?? arms.find((item)=>!item.pageTarget)?.key ?? 'control');
|
|
78
79
|
else router.push(`${testUrl}#section-${section}`);
|
|
79
80
|
};
|
|
80
|
-
const picker = arm && collection ? /*#__PURE__*/ _jsx(
|
|
81
|
+
const picker = arm && collection ? /*#__PURE__*/ _jsx(PageCombobox, {
|
|
81
82
|
collection: collection,
|
|
82
83
|
test: test,
|
|
83
84
|
armKey: arm.key,
|
|
@@ -173,6 +174,10 @@ import { useTransition } from '../readiness/useTransition.js';
|
|
|
173
174
|
collection: collection,
|
|
174
175
|
children: picker
|
|
175
176
|
}) : null,
|
|
177
|
+
arm ? /*#__PURE__*/ _jsx(FieldErrors, {
|
|
178
|
+
test: test,
|
|
179
|
+
path: `arms.${doc.arms.findIndex((item)=>item.key === arm.key)}.pageTarget`
|
|
180
|
+
}) : null,
|
|
176
181
|
/*#__PURE__*/ _jsxs("div", {
|
|
177
182
|
className: "xp-new-test-actions",
|
|
178
183
|
children: [
|
|
@@ -2,5 +2,5 @@ import type { ReactNode } from 'react';
|
|
|
2
2
|
import type { PageCollection } from './pagePicker.model.js';
|
|
3
3
|
export declare function CopyRoute({ collection, children }: {
|
|
4
4
|
collection: PageCollection;
|
|
5
|
-
children
|
|
5
|
+
children?: ReactNode;
|
|
6
6
|
}): import("react").JSX.Element;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { TestDocApi } from '../contracts.js';
|
|
2
2
|
import type { PageCollection } from './pagePicker.model.js';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import './pagePicker.css';
|
|
4
|
+
/** One input owns focus; list options are navigated through aria-activedescendant. */
|
|
5
|
+
export declare function PageCombobox({ collection, test, armKey, apiRoute }: {
|
|
5
6
|
collection: PageCollection;
|
|
6
7
|
test: TestDocApi;
|
|
7
8
|
armKey: string;
|
|
8
9
|
apiRoute: string;
|
|
9
|
-
onChoose?: () => void;
|
|
10
10
|
}): import("react").JSX.Element;
|