@delmaredigital/payload-experiments 0.2.0-rc.3 → 0.2.0-rc.5
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 +22 -0
- package/dist/admin/PreviewLinks.js +8 -4
- package/dist/admin/TestsDashboardCards.d.ts +3 -0
- package/dist/admin/TestsDashboardCards.js +52 -0
- package/dist/admin/TestsNavLink.d.ts +3 -1
- package/dist/admin/TestsNavLink.js +62 -18
- 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/copy/review.d.ts +1 -0
- package/dist/admin/copy/review.js +1 -0
- package/dist/admin/copy/surface.d.ts +4 -0
- package/dist/admin/copy/surface.js +4 -0
- package/dist/admin/dashboard.css +35 -0
- package/dist/admin/paths.d.ts +1 -0
- package/dist/admin/paths.js +1 -0
- package/dist/admin/previewLinks.model.d.ts +9 -0
- package/dist/admin/previewLinks.model.js +34 -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 +44 -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/events.js +1 -0
- package/dist/collections/identities.js +1 -0
- package/dist/collections/layers.js +1 -0
- package/dist/collections/metricValidation.d.ts +3 -0
- package/dist/collections/metricValidation.js +9 -0
- package/dist/collections/metrics.js +4 -5
- package/dist/collections/phases.js +1 -0
- package/dist/collections/snapshots.js +1 -0
- package/dist/exports/adminClient.d.ts +1 -0
- package/dist/exports/adminClient.js +1 -0
- package/dist/globals/state.js +1 -0
- package/dist/plugin.js +8 -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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** every Payload token reference lives in theme.css; porting to Payload 4 edits that file only */
|
|
2
|
+
export declare const theme: {
|
|
3
|
+
readonly color: {
|
|
4
|
+
readonly bg: "var(--xp-bg)";
|
|
5
|
+
readonly text: "var(--xp-text)";
|
|
6
|
+
readonly surface: "var(--xp-surface)";
|
|
7
|
+
readonly surfaceRaised: "var(--xp-surface-raised)";
|
|
8
|
+
readonly border: "var(--xp-border)";
|
|
9
|
+
readonly borderStrong: "var(--xp-border-strong)";
|
|
10
|
+
readonly borderControl: "var(--xp-border-control)";
|
|
11
|
+
readonly inputBorder: "var(--xp-input-border)";
|
|
12
|
+
readonly borderAccent: "var(--xp-border-accent)";
|
|
13
|
+
readonly accent: "var(--xp-accent)";
|
|
14
|
+
readonly textMuted: "var(--xp-text-muted)";
|
|
15
|
+
readonly textStrong: "var(--xp-text-strong)";
|
|
16
|
+
readonly textEmphasis: "var(--xp-text-emphasis)";
|
|
17
|
+
readonly inputBg: "var(--xp-input-bg)";
|
|
18
|
+
readonly overlay: "var(--xp-overlay)";
|
|
19
|
+
readonly successSurface: "var(--xp-success-surface)";
|
|
20
|
+
readonly successBg: "var(--xp-success-bg)";
|
|
21
|
+
readonly success: "var(--xp-success)";
|
|
22
|
+
readonly successText: "var(--xp-success-text)";
|
|
23
|
+
readonly successTextStrong: "var(--xp-success-text-strong)";
|
|
24
|
+
readonly warningSurface: "var(--xp-warning-surface)";
|
|
25
|
+
readonly warningBg: "var(--xp-warning-bg)";
|
|
26
|
+
readonly warning: "var(--xp-warning)";
|
|
27
|
+
readonly warningText: "var(--xp-warning-text)";
|
|
28
|
+
readonly warningTextStrong: "var(--xp-warning-text-strong)";
|
|
29
|
+
readonly errorSurface: "var(--xp-error-surface)";
|
|
30
|
+
readonly error: "var(--xp-error)";
|
|
31
|
+
readonly errorText: "var(--xp-error-text)";
|
|
32
|
+
};
|
|
33
|
+
readonly radius: {
|
|
34
|
+
readonly small: "var(--xp-radius)";
|
|
35
|
+
readonly large: "var(--xp-radius-large)";
|
|
36
|
+
};
|
|
37
|
+
readonly space: {
|
|
38
|
+
readonly 1: "var(--xp-space-1)";
|
|
39
|
+
readonly 2: "var(--xp-space-2)";
|
|
40
|
+
readonly 3: "var(--xp-space-3)";
|
|
41
|
+
readonly 4: "var(--xp-space-4)";
|
|
42
|
+
readonly 5: "var(--xp-space-5)";
|
|
43
|
+
readonly 6: "var(--xp-space-6)";
|
|
44
|
+
};
|
|
45
|
+
readonly font: {
|
|
46
|
+
readonly body: "var(--xp-font-body)";
|
|
47
|
+
readonly small: "var(--xp-font-size-small)";
|
|
48
|
+
readonly size: "var(--xp-font-size-body)";
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** every Payload token reference lives in theme.css; porting to Payload 4 edits that file only */ export const theme = {
|
|
2
|
+
color: {
|
|
3
|
+
bg: 'var(--xp-bg)',
|
|
4
|
+
text: 'var(--xp-text)',
|
|
5
|
+
surface: 'var(--xp-surface)',
|
|
6
|
+
surfaceRaised: 'var(--xp-surface-raised)',
|
|
7
|
+
border: 'var(--xp-border)',
|
|
8
|
+
borderStrong: 'var(--xp-border-strong)',
|
|
9
|
+
borderControl: 'var(--xp-border-control)',
|
|
10
|
+
inputBorder: 'var(--xp-input-border)',
|
|
11
|
+
borderAccent: 'var(--xp-border-accent)',
|
|
12
|
+
accent: 'var(--xp-accent)',
|
|
13
|
+
textMuted: 'var(--xp-text-muted)',
|
|
14
|
+
textStrong: 'var(--xp-text-strong)',
|
|
15
|
+
textEmphasis: 'var(--xp-text-emphasis)',
|
|
16
|
+
inputBg: 'var(--xp-input-bg)',
|
|
17
|
+
overlay: 'var(--xp-overlay)',
|
|
18
|
+
successSurface: 'var(--xp-success-surface)',
|
|
19
|
+
successBg: 'var(--xp-success-bg)',
|
|
20
|
+
success: 'var(--xp-success)',
|
|
21
|
+
successText: 'var(--xp-success-text)',
|
|
22
|
+
successTextStrong: 'var(--xp-success-text-strong)',
|
|
23
|
+
warningSurface: 'var(--xp-warning-surface)',
|
|
24
|
+
warningBg: 'var(--xp-warning-bg)',
|
|
25
|
+
warning: 'var(--xp-warning)',
|
|
26
|
+
warningText: 'var(--xp-warning-text)',
|
|
27
|
+
warningTextStrong: 'var(--xp-warning-text-strong)',
|
|
28
|
+
errorSurface: 'var(--xp-error-surface)',
|
|
29
|
+
error: 'var(--xp-error)',
|
|
30
|
+
errorText: 'var(--xp-error-text)'
|
|
31
|
+
},
|
|
32
|
+
radius: {
|
|
33
|
+
small: 'var(--xp-radius)',
|
|
34
|
+
large: 'var(--xp-radius-large)'
|
|
35
|
+
},
|
|
36
|
+
space: {
|
|
37
|
+
1: 'var(--xp-space-1)',
|
|
38
|
+
2: 'var(--xp-space-2)',
|
|
39
|
+
3: 'var(--xp-space-3)',
|
|
40
|
+
4: 'var(--xp-space-4)',
|
|
41
|
+
5: 'var(--xp-space-5)',
|
|
42
|
+
6: 'var(--xp-space-6)'
|
|
43
|
+
},
|
|
44
|
+
font: {
|
|
45
|
+
body: 'var(--xp-font-body)',
|
|
46
|
+
small: 'var(--xp-font-size-small)',
|
|
47
|
+
size: 'var(--xp-font-size-body)'
|
|
48
|
+
}
|
|
49
|
+
};
|
|
@@ -18,7 +18,11 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
|
|
|
18
18
|
let id;
|
|
19
19
|
if (tail.length === 0) route = 'home';
|
|
20
20
|
else if (tail.length === 1 && tail[0] === 'new') route = 'new';
|
|
21
|
-
else if (tail.length === 1)
|
|
21
|
+
else if (tail.length === 1 && tail[0] === 'goals') route = 'goals';
|
|
22
|
+
else if (tail.length === 2 && tail[0] === 'goals') {
|
|
23
|
+
route = tail[1] === 'new' ? 'goalNew' : 'goal';
|
|
24
|
+
if (route === 'goal') id = tail[1];
|
|
25
|
+
} else if (tail.length === 1) {
|
|
22
26
|
route = 'test';
|
|
23
27
|
id = tail[0];
|
|
24
28
|
} else if (tail.length === 2 && tail[1] === 'results') {
|
|
@@ -41,6 +45,8 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
|
|
|
41
45
|
path: `${login}?redirect=${encodeURIComponent(currentPath)}`
|
|
42
46
|
}));
|
|
43
47
|
}
|
|
48
|
+
// Keep the server export importable in plain Node; Next loads the CSS-bearing client boundary when this view renders.
|
|
49
|
+
const { RootViewMessage } = await import('../components/RootViewMessage.js');
|
|
44
50
|
const options = xpOptionsFromReq(req);
|
|
45
51
|
async function permits(access) {
|
|
46
52
|
try {
|
|
@@ -60,12 +66,7 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
|
|
|
60
66
|
canManage,
|
|
61
67
|
canReadResults
|
|
62
68
|
}) !== 'ok') {
|
|
63
|
-
return /*#__PURE__*/ _jsx(
|
|
64
|
-
style: {
|
|
65
|
-
padding: 'var(--base)',
|
|
66
|
-
color: 'var(--theme-text)',
|
|
67
|
-
background: 'var(--theme-bg)'
|
|
68
|
-
},
|
|
69
|
+
return /*#__PURE__*/ _jsx(RootViewMessage, {
|
|
69
70
|
children: SURFACE_COPY.noAccess
|
|
70
71
|
});
|
|
71
72
|
}
|
|
@@ -131,7 +132,11 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
|
|
|
131
132
|
}
|
|
132
133
|
}))).flat() : undefined;
|
|
133
134
|
const descriptions = options.admin?.descriptions;
|
|
135
|
+
const returnToTest = (await searchParams)?.return;
|
|
134
136
|
const clientProps = {
|
|
137
|
+
...typeof returnToTest === 'string' && /^[\w-]+$/.test(returnToTest) ? {
|
|
138
|
+
returnToTest
|
|
139
|
+
} : {},
|
|
135
140
|
route,
|
|
136
141
|
...id === undefined ? {} : {
|
|
137
142
|
id
|
|
@@ -155,6 +160,12 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
|
|
|
155
160
|
}
|
|
156
161
|
} : {}
|
|
157
162
|
};
|
|
163
|
+
function TestsSurfaceFallback() {
|
|
164
|
+
return /*#__PURE__*/ _jsx(RootViewMessage, {
|
|
165
|
+
alert: true,
|
|
166
|
+
children: SURFACE_COPY.notInstalled
|
|
167
|
+
});
|
|
168
|
+
}
|
|
158
169
|
return RenderServerComponent({
|
|
159
170
|
Component: XP_TESTS_SURFACE,
|
|
160
171
|
Fallback: TestsSurfaceFallback,
|
|
@@ -162,14 +173,3 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
|
|
|
162
173
|
clientProps
|
|
163
174
|
});
|
|
164
175
|
}
|
|
165
|
-
function TestsSurfaceFallback() {
|
|
166
|
-
return /*#__PURE__*/ _jsx("div", {
|
|
167
|
-
role: "alert",
|
|
168
|
-
style: {
|
|
169
|
-
padding: 'var(--base)',
|
|
170
|
-
color: 'var(--theme-text)',
|
|
171
|
-
background: 'var(--theme-bg)'
|
|
172
|
-
},
|
|
173
|
-
children: SURFACE_COPY.notInstalled
|
|
174
|
-
});
|
|
175
|
-
}
|
|
@@ -12,6 +12,7 @@ export function layersCollection(options) {
|
|
|
12
12
|
slug: 'xp-layers',
|
|
13
13
|
graphQL: false,
|
|
14
14
|
disableDuplicate: true,
|
|
15
|
+
versions: false,
|
|
15
16
|
// group:false hides navigation while keeping collection routes reachable (hidden causes 404s).
|
|
16
17
|
labels: {
|
|
17
18
|
singular: 'Test group',
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Shared with the goals form; preserve Payload's field validation messages. */
|
|
2
|
+
export declare function validateCappingType(value: unknown, capValue: unknown, sourceKind?: string): true | string;
|
|
3
|
+
export declare function validateCappingValue(value: unknown, type: unknown): true | string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Shared with the goals form; preserve Payload's field validation messages. */ export function validateCappingType(value, capValue, sourceKind) {
|
|
2
|
+
const hasCapping = value != null || capValue != null;
|
|
3
|
+
if (hasCapping && sourceKind && sourceKind !== 'revenue') return 'Count and yes-or-no goals cannot use a limit.';
|
|
4
|
+
return !hasCapping || value === 'percentile' || value === 'absolute' || 'Choose how to set the limit.';
|
|
5
|
+
}
|
|
6
|
+
export function validateCappingValue(value, type) {
|
|
7
|
+
if (value == null && !type) return true;
|
|
8
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0 && (type === 'absolute' || type === 'percentile' && value > 0 && value <= 1) || 'Enter a valid limit (for past amounts, use a number greater than 0 and at most 1).';
|
|
9
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { XP_METRIC_SOURCE_SELECT } from '../admin/paths.js';
|
|
2
2
|
import { managedAccess } from './access.js';
|
|
3
3
|
import { serializeMetricSources } from './serialize.js';
|
|
4
|
+
import { validateCappingType, validateCappingValue } from './metricValidation.js';
|
|
4
5
|
export function metricsCollection(options) {
|
|
5
6
|
const sources = serializeMetricSources(options);
|
|
6
7
|
return {
|
|
7
8
|
slug: 'xp-metrics',
|
|
8
9
|
graphQL: false,
|
|
9
10
|
disableDuplicate: true,
|
|
11
|
+
versions: false,
|
|
10
12
|
// group:false hides navigation while keeping collection routes reachable (hidden causes 404s).
|
|
11
13
|
labels: {
|
|
12
14
|
singular: 'Goal',
|
|
@@ -125,10 +127,8 @@ export function metricsCollection(options) {
|
|
|
125
127
|
description: 'Choose whether the limit comes from past amounts or a fixed amount.'
|
|
126
128
|
},
|
|
127
129
|
validate: (value, { data, siblingData })=>{
|
|
128
|
-
const hasCapping = value != null || siblingData?.value != null;
|
|
129
130
|
const source = sources.find((source)=>source.id === data?.source);
|
|
130
|
-
|
|
131
|
-
return !hasCapping || value === 'percentile' || value === 'absolute' || 'Choose how to set the limit.';
|
|
131
|
+
return validateCappingType(value, siblingData?.value, source?.kind);
|
|
132
132
|
}
|
|
133
133
|
},
|
|
134
134
|
{
|
|
@@ -140,8 +140,7 @@ export function metricsCollection(options) {
|
|
|
140
140
|
description: 'For past amounts, enter how much of the usual range to keep, such as 0.99 to limit only the largest 1%; or enter a fixed amount.'
|
|
141
141
|
},
|
|
142
142
|
validate: (value, { siblingData })=>{
|
|
143
|
-
|
|
144
|
-
return typeof value === 'number' && Number.isFinite(value) && value >= 0 && (siblingData?.type === 'absolute' || siblingData?.type === 'percentile' && value > 0 && value <= 1) || 'Enter a valid limit (for past amounts, use a number greater than 0 and at most 1).';
|
|
143
|
+
return validateCappingValue(value, siblingData?.type);
|
|
145
144
|
}
|
|
146
145
|
}
|
|
147
146
|
]
|
|
@@ -3,3 +3,4 @@ export { MetricSourceSelect } from '../admin/MetricSourceSelect.js';
|
|
|
3
3
|
export { ArmSelectField } from '../admin/armSelect/ArmSelectField.js';
|
|
4
4
|
export { TestsNavLink } from '../admin/TestsNavLink.js';
|
|
5
5
|
export { TestsSurface } from '../admin/surface/TestsSurface.js';
|
|
6
|
+
export { TestsDashboardCards } from '../admin/TestsDashboardCards.js';
|
|
@@ -4,3 +4,4 @@ export { MetricSourceSelect } from '../admin/MetricSourceSelect.js';
|
|
|
4
4
|
export { ArmSelectField } from '../admin/armSelect/ArmSelectField.js';
|
|
5
5
|
export { TestsNavLink } from '../admin/TestsNavLink.js';
|
|
6
6
|
export { TestsSurface } from '../admin/surface/TestsSurface.js';
|
|
7
|
+
export { TestsDashboardCards } from '../admin/TestsDashboardCards.js';
|
package/dist/globals/state.js
CHANGED
package/dist/plugin.js
CHANGED
|
@@ -15,6 +15,8 @@ export function createExperimentsPlugin(input) {
|
|
|
15
15
|
// Erase the user subtype only at this non-generic factory boundary.
|
|
16
16
|
const { collections, globals } = buildCollections(options);
|
|
17
17
|
const onInit = createOnInit(options);
|
|
18
|
+
const beforeDashboard = config.admin?.components?.beforeDashboard ?? [];
|
|
19
|
+
const beforeNavLinks = config.admin?.components?.beforeNavLinks ?? [];
|
|
18
20
|
return {
|
|
19
21
|
...config,
|
|
20
22
|
admin: {
|
|
@@ -35,8 +37,12 @@ export function createExperimentsPlugin(input) {
|
|
|
35
37
|
path: '/experiments/:segments*'
|
|
36
38
|
}
|
|
37
39
|
},
|
|
38
|
-
|
|
39
|
-
...
|
|
40
|
+
beforeDashboard: beforeDashboard.includes(paths.XP_TESTS_DASHBOARD_CARDS) ? beforeDashboard : [
|
|
41
|
+
...beforeDashboard,
|
|
42
|
+
paths.XP_TESTS_DASHBOARD_CARDS
|
|
43
|
+
],
|
|
44
|
+
beforeNavLinks: beforeNavLinks.includes(paths.XP_TESTS_NAV_LINK) ? beforeNavLinks : [
|
|
45
|
+
...beforeNavLinks,
|
|
40
46
|
paths.XP_TESTS_NAV_LINK
|
|
41
47
|
]
|
|
42
48
|
}
|
|
@@ -3,8 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useId, useRef, useState } from 'react';
|
|
4
4
|
import { CreateRefused, createTest } from './createTest.js';
|
|
5
5
|
import { editorCopy } from './copy.js';
|
|
6
|
+
import './editor.css';
|
|
6
7
|
export function CreateExperimentDrawer({ onCreate, onClose, initialName = '' }) {
|
|
7
8
|
const titleId = useId();
|
|
9
|
+
const nameId = useId();
|
|
8
10
|
const [name, setName] = useState(initialName);
|
|
9
11
|
const inFlight = useRef(false);
|
|
10
12
|
const [pending, setPending] = useState(false);
|
|
@@ -30,27 +32,26 @@ export function CreateExperimentDrawer({ onCreate, onClose, initialName = '' })
|
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
34
|
return /*#__PURE__*/ _jsxs("aside", {
|
|
35
|
+
className: "xp-slot-root xp-slot-drawer",
|
|
33
36
|
role: "dialog",
|
|
34
37
|
"aria-labelledby": titleId,
|
|
35
|
-
style: {
|
|
36
|
-
padding: 16,
|
|
37
|
-
border: '1px solid #aaa',
|
|
38
|
-
background: 'Canvas',
|
|
39
|
-
color: 'CanvasText'
|
|
40
|
-
},
|
|
41
38
|
children: [
|
|
42
39
|
/*#__PURE__*/ _jsx("h3", {
|
|
40
|
+
className: "xp-slot-title",
|
|
43
41
|
id: titleId,
|
|
44
42
|
children: editorCopy.createLabel
|
|
45
43
|
}),
|
|
46
|
-
/*#__PURE__*/ _jsxs("
|
|
47
|
-
|
|
48
|
-
display: 'block',
|
|
49
|
-
marginBottom: 8
|
|
50
|
-
},
|
|
44
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
45
|
+
className: "xp-slot-field",
|
|
51
46
|
children: [
|
|
52
|
-
|
|
47
|
+
/*#__PURE__*/ _jsx("label", {
|
|
48
|
+
className: "xp-slot-label",
|
|
49
|
+
htmlFor: nameId,
|
|
50
|
+
children: editorCopy.name
|
|
51
|
+
}),
|
|
53
52
|
/*#__PURE__*/ _jsx("input", {
|
|
53
|
+
className: "xp-slot-input",
|
|
54
|
+
id: nameId,
|
|
54
55
|
value: name,
|
|
55
56
|
disabled: pending,
|
|
56
57
|
onChange: (event)=>setName(event.currentTarget.value)
|
|
@@ -58,22 +59,30 @@ export function CreateExperimentDrawer({ onCreate, onClose, initialName = '' })
|
|
|
58
59
|
]
|
|
59
60
|
}),
|
|
60
61
|
error ? /*#__PURE__*/ _jsx("p", {
|
|
62
|
+
className: "xp-slot-error",
|
|
61
63
|
role: "alert",
|
|
62
64
|
children: error
|
|
63
65
|
}) : null,
|
|
64
|
-
/*#__PURE__*/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
66
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
67
|
+
className: "xp-slot-actions",
|
|
68
|
+
children: [
|
|
69
|
+
/*#__PURE__*/ _jsx("button", {
|
|
70
|
+
className: "xp-slot-button xp-slot-button-primary",
|
|
71
|
+
type: "button",
|
|
72
|
+
disabled: pending || !name.trim(),
|
|
73
|
+
onClick: ()=>{
|
|
74
|
+
void submitNew();
|
|
75
|
+
},
|
|
76
|
+
children: pending ? editorCopy.creating : editorCopy.createLabel
|
|
77
|
+
}),
|
|
78
|
+
/*#__PURE__*/ _jsx("button", {
|
|
79
|
+
className: "xp-slot-button",
|
|
80
|
+
type: "button",
|
|
81
|
+
disabled: pending,
|
|
82
|
+
onClick: onClose,
|
|
83
|
+
children: editorCopy.cancel
|
|
84
|
+
})
|
|
85
|
+
]
|
|
77
86
|
})
|
|
78
87
|
]
|
|
79
88
|
});
|