@sanity/personalization-plugin 2.4.2 → 2.5.0-field-level-personalization.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks-cjs/fieldExperiments.js +507 -0
- package/dist/_chunks-cjs/fieldExperiments.js.map +1 -0
- package/dist/_chunks-es/fieldExperiments.mjs +511 -0
- package/dist/_chunks-es/fieldExperiments.mjs.map +1 -0
- package/dist/growthbook/index.js +3 -3
- package/dist/growthbook/index.js.map +1 -1
- package/dist/growthbook/index.mjs +1 -1
- package/dist/index.d.mts +33 -12
- package/dist/index.d.ts +33 -12
- package/dist/index.js +157 -280
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +159 -280
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/{ExperimentItem.tsx → ArrayItem.tsx} +1 -2
- package/src/components/Select.tsx +1 -1
- package/src/components/{Array.tsx → experiment/Array.tsx} +2 -2
- package/src/components/{ExperimentContext.tsx → experiment/Context.tsx} +2 -2
- package/src/components/{ExperimentField.tsx → experiment/Field.tsx} +11 -8
- package/src/components/{ExperimentInput.tsx → experiment/Input.tsx} +4 -4
- package/src/components/{VariantPreview.tsx → experiment/VariantPreview.tsx} +2 -2
- package/src/components/experiment/index.ts +6 -0
- package/src/components/personalization/Array.tsx +59 -0
- package/src/components/personalization/Context.tsx +61 -0
- package/src/components/personalization/Field.tsx +134 -0
- package/src/components/personalization/SegmentInput.tsx +19 -0
- package/src/components/personalization/SegmentPreview.tsx +71 -0
- package/src/components/personalization/index.ts +5 -0
- package/src/fieldExperiments.tsx +43 -13
- package/src/fieldPersonalization.tsx +254 -0
- package/src/index.ts +1 -0
- package/src/types.ts +20 -2
- package/src/utils/clearChildGroups.ts +33 -0
- /package/src/components/{VariantInput.tsx → experiment/VariantInput.tsx} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,105 +1,82 @@
|
|
|
1
|
+
import { clearChildrenGroups, CloseIcon, flattenSchemaType, ArrayItem } from "./_chunks-es/fieldExperiments.mjs";
|
|
2
|
+
import { fieldLevelExperiments } from "./_chunks-es/fieldExperiments.mjs";
|
|
1
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useClient, useWorkspace,
|
|
3
|
-
import { Stack, Inline, Button
|
|
4
|
+
import { useClient, useWorkspace, defineDocumentFieldAction, set, unset, useFormValue, isReference, isImage, definePlugin, isObjectInputProps, defineType, defineField } from "sanity";
|
|
5
|
+
import { Stack, Inline, Button } from "@sanity/ui";
|
|
4
6
|
import { uuid } from "@sanity/uuid";
|
|
5
|
-
import { createContext, useMemo, useContext, useCallback,
|
|
7
|
+
import { createContext, useMemo, useContext, useCallback, useState, useEffect } from "react";
|
|
6
8
|
import equal from "fast-deep-equal";
|
|
7
9
|
import { suspend } from "suspend-react";
|
|
8
|
-
import {
|
|
10
|
+
import { IoMdPeople } from "react-icons/io";
|
|
9
11
|
const CONFIG_DEFAULT = {
|
|
10
12
|
fields: [],
|
|
11
13
|
apiVersion: "2024-11-07",
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}, ExperimentContext = createContext({
|
|
14
|
+
personalizationNameOverride: "personalization",
|
|
15
|
+
segmentNameOverride: "segment",
|
|
16
|
+
segmentId: "segmentId",
|
|
17
|
+
segmentArrayName: "segments"
|
|
18
|
+
}, PersonalizationContext = createContext({
|
|
18
19
|
...CONFIG_DEFAULT,
|
|
19
|
-
|
|
20
|
+
segments: []
|
|
20
21
|
});
|
|
21
|
-
function
|
|
22
|
-
return useContext(
|
|
22
|
+
function usePersonalizationContext() {
|
|
23
|
+
return useContext(PersonalizationContext);
|
|
23
24
|
}
|
|
24
|
-
function
|
|
25
|
-
const {
|
|
25
|
+
function PersonalizationProvider(props) {
|
|
26
|
+
const { personalizationFieldPluginConfig } = props, client = useClient({ apiVersion: personalizationFieldPluginConfig.apiVersion }), workspace = useWorkspace(), segments = Array.isArray(personalizationFieldPluginConfig.segments) ? personalizationFieldPluginConfig.segments : suspend(
|
|
26
27
|
// eslint-disable-next-line require-await
|
|
27
|
-
async () => typeof
|
|
28
|
+
async () => typeof personalizationFieldPluginConfig.segments == "function" ? personalizationFieldPluginConfig.segments(client) : personalizationFieldPluginConfig.segments,
|
|
28
29
|
[workspace],
|
|
29
30
|
{ equal }
|
|
30
31
|
), context = useMemo(
|
|
31
|
-
() => ({ ...
|
|
32
|
-
[
|
|
32
|
+
() => ({ ...personalizationFieldPluginConfig, segments }),
|
|
33
|
+
[personalizationFieldPluginConfig, segments]
|
|
33
34
|
);
|
|
34
|
-
return /* @__PURE__ */ jsx(
|
|
35
|
+
return /* @__PURE__ */ jsx(PersonalizationContext.Provider, { value: context, children: props.renderDefault(props) });
|
|
35
36
|
}
|
|
36
37
|
const ArrayInput = (props) => {
|
|
37
|
-
const
|
|
38
|
-
async (
|
|
38
|
+
const { onItemAppend, segmentName, segmentId } = props, { segments } = usePersonalizationContext(), handleClick = useCallback(
|
|
39
|
+
async (segment) => {
|
|
39
40
|
const item = {
|
|
40
41
|
_key: uuid(),
|
|
41
|
-
[
|
|
42
|
-
|
|
43
|
-
_type: variantName
|
|
42
|
+
[segmentId]: segment.id,
|
|
43
|
+
_type: segmentName
|
|
44
44
|
};
|
|
45
45
|
onItemAppend(item);
|
|
46
46
|
},
|
|
47
|
-
[
|
|
48
|
-
),
|
|
47
|
+
[segmentId, segmentName, onItemAppend]
|
|
48
|
+
), usedSegments = (props.value || [])?.map((segment) => segment[segmentId]);
|
|
49
49
|
return /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
50
50
|
props.renderDefault({ ...props, arrayFunctions: () => null }),
|
|
51
|
-
/* @__PURE__ */ jsx(Inline, { space: 1, children:
|
|
51
|
+
/* @__PURE__ */ jsx(Inline, { space: 1, children: segments.map((segment) => /* @__PURE__ */ jsx(
|
|
52
52
|
Button,
|
|
53
53
|
{
|
|
54
|
-
text: `Add ${
|
|
54
|
+
text: `Add ${segment.label}`,
|
|
55
55
|
mode: "ghost",
|
|
56
|
-
disabled:
|
|
57
|
-
onClick: () => handleClick(
|
|
56
|
+
disabled: usedSegments?.includes(segment.id),
|
|
57
|
+
onClick: () => handleClick(segment)
|
|
58
58
|
},
|
|
59
|
-
`${
|
|
59
|
+
`${segment.id}`
|
|
60
60
|
)) })
|
|
61
61
|
] });
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
"svg",
|
|
65
|
-
{
|
|
66
|
-
"data-sanity-icon": "close",
|
|
67
|
-
width: "1em",
|
|
68
|
-
height: "1em",
|
|
69
|
-
viewBox: "0 0 25 25",
|
|
70
|
-
fill: "none",
|
|
71
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
72
|
-
...props,
|
|
73
|
-
ref,
|
|
74
|
-
children: /* @__PURE__ */ jsx(
|
|
75
|
-
"path",
|
|
76
|
-
{
|
|
77
|
-
d: "M18 7L7 18M7 7L18 18",
|
|
78
|
-
stroke: "currentColor",
|
|
79
|
-
strokeWidth: 1.2,
|
|
80
|
-
strokeLinejoin: "round"
|
|
81
|
-
}
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
);
|
|
85
|
-
}), useAddExperimentAction = (props) => {
|
|
86
|
-
const { onChange, active, experimentNameOverride } = props, handleAddAction = useCallback(() => {
|
|
62
|
+
}, useAddExperimentAction = (props) => {
|
|
63
|
+
const { onChange, active, personalizationNameOverride } = props, handleAddAction = useCallback(() => {
|
|
87
64
|
onChange([set(!active, ["active"])]);
|
|
88
65
|
}, [onChange, active]);
|
|
89
66
|
return {
|
|
90
|
-
title: `Add ${
|
|
67
|
+
title: `Add ${personalizationNameOverride}`,
|
|
91
68
|
type: "action",
|
|
92
|
-
icon:
|
|
69
|
+
icon: IoMdPeople,
|
|
93
70
|
onAction: handleAddAction,
|
|
94
71
|
renderAsButton: !0
|
|
95
72
|
};
|
|
96
73
|
}, useRemoveExperimentAction = (props) => {
|
|
97
|
-
const { onChange, active,
|
|
98
|
-
const activeId = ["active"],
|
|
99
|
-
onChange([set(!active, activeId), unset(
|
|
100
|
-
}, [onChange, active,
|
|
74
|
+
const { onChange, active, personalizationNameOverride, segmentNameOverride } = props, handleClearAction = useCallback(() => {
|
|
75
|
+
const activeId = ["active"], segments = [`${segmentNameOverride}s`];
|
|
76
|
+
onChange([set(!active, activeId), unset(segments)]);
|
|
77
|
+
}, [onChange, active, segmentNameOverride]);
|
|
101
78
|
return {
|
|
102
|
-
title: `Remove ${
|
|
79
|
+
title: `Remove ${personalizationNameOverride}`,
|
|
103
80
|
type: "action",
|
|
104
81
|
icon: CloseIcon,
|
|
105
82
|
onAction: handleClearAction,
|
|
@@ -109,115 +86,57 @@ const ArrayInput = (props) => {
|
|
|
109
86
|
onChange,
|
|
110
87
|
inputId,
|
|
111
88
|
active,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
variantNameOverride
|
|
89
|
+
personalizationNameOverride,
|
|
90
|
+
segmentNameOverride
|
|
115
91
|
}) => {
|
|
116
92
|
const removeAction = defineDocumentFieldAction({
|
|
117
|
-
name: `Remove ${
|
|
93
|
+
name: `Remove ${personalizationNameOverride}`,
|
|
118
94
|
useAction: (props) => useRemoveExperimentAction({
|
|
119
95
|
active: !0,
|
|
120
96
|
onChange,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
variantNameOverride
|
|
97
|
+
personalizationNameOverride,
|
|
98
|
+
segmentNameOverride
|
|
124
99
|
})
|
|
125
100
|
}), addAction = defineDocumentFieldAction({
|
|
126
|
-
name: `Add ${
|
|
101
|
+
name: `Add ${personalizationNameOverride}`,
|
|
127
102
|
useAction: (props) => useAddExperimentAction({
|
|
128
103
|
active: !1,
|
|
129
104
|
onChange,
|
|
130
|
-
|
|
105
|
+
personalizationNameOverride
|
|
131
106
|
})
|
|
132
107
|
});
|
|
133
108
|
return active ? removeAction : addAction;
|
|
134
|
-
},
|
|
135
|
-
const { onChange } = props.inputProps, { inputId,
|
|
109
|
+
}, Field = (props) => {
|
|
110
|
+
const { onChange } = props.inputProps, { inputId, personalizationNameOverride, segmentNameOverride } = props, active = props.value?.active, actionProps = useMemo(
|
|
136
111
|
() => ({
|
|
137
112
|
onChange,
|
|
138
113
|
inputId,
|
|
139
114
|
active,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
variantNameOverride
|
|
115
|
+
personalizationNameOverride,
|
|
116
|
+
segmentNameOverride
|
|
143
117
|
}),
|
|
144
|
-
[onChange, inputId, active,
|
|
118
|
+
[onChange, inputId, active, personalizationNameOverride, segmentNameOverride]
|
|
145
119
|
), memoizedActions = useMemo(() => {
|
|
146
120
|
const oldActions = props.actions || [];
|
|
147
121
|
return [createActions(actionProps), ...oldActions];
|
|
148
|
-
}, [actionProps, props.actions]),
|
|
149
|
-
()
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
)
|
|
155
|
-
return props.renderDefault(withActionProps);
|
|
156
|
-
}, Select = (props) => {
|
|
157
|
-
const {
|
|
158
|
-
value,
|
|
159
|
-
// Current field value
|
|
160
|
-
onChange,
|
|
161
|
-
// Method to handle patch events,
|
|
162
|
-
elementProps,
|
|
163
|
-
listOptions,
|
|
164
|
-
handleChange
|
|
165
|
-
} = props;
|
|
166
|
-
return /* @__PURE__ */ jsxs(
|
|
167
|
-
Select$1,
|
|
168
|
-
{
|
|
169
|
-
...elementProps,
|
|
170
|
-
fontSize: 2,
|
|
171
|
-
padding: 3,
|
|
172
|
-
space: [3, 3, 4],
|
|
173
|
-
value: value || "",
|
|
174
|
-
onChange: (event) => handleChange(event, onChange),
|
|
175
|
-
children: [
|
|
176
|
-
/* @__PURE__ */ jsx("option", { value: "", children: "Select an option..." }),
|
|
177
|
-
listOptions.map(({ value: optionValue, title }) => /* @__PURE__ */ jsx("option", { value: optionValue, children: title }, optionValue))
|
|
178
|
-
]
|
|
179
|
-
}
|
|
180
|
-
);
|
|
181
|
-
}, formatlistOptions = (experiments) => experiments.map((experiment) => ({
|
|
182
|
-
title: experiment.label,
|
|
183
|
-
value: experiment.id
|
|
184
|
-
})), ExperimentInput = (props) => {
|
|
185
|
-
const { experiments } = useExperimentContext(), id = useFormValue(["_id"]), additionalChangePath = useMemo(
|
|
186
|
-
() => [...props.path.slice(0, -1), `${props.variantNameOverride}s`],
|
|
187
|
-
[props.variantNameOverride, props.path]
|
|
188
|
-
), subValues = useFormValue(additionalChangePath), { patch } = useDocumentOperation(getPublishedId(id), props.schemaType.name), handleChange = useCallback(
|
|
189
|
-
(event, onChange) => {
|
|
190
|
-
const inputValue = event.currentTarget.value;
|
|
191
|
-
if (onChange(inputValue ? set(inputValue) : unset()), subValues) {
|
|
192
|
-
const patchEvent = {
|
|
193
|
-
unset: [additionalChangePath.join(".")]
|
|
194
|
-
};
|
|
195
|
-
patch.execute([patchEvent]);
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
[patch, subValues, additionalChangePath]
|
|
199
|
-
);
|
|
200
|
-
return experiments.length ? /* @__PURE__ */ jsx(Select, { ...props, listOptions: formatlistOptions(experiments), handleChange }) : /* @__PURE__ */ jsx(Card, { padding: [3, 3, 4], radius: 2, shadow: 1, tone: "caution", children: /* @__PURE__ */ jsxs(Text, { align: "center", size: [2, 2, 3], children: [
|
|
201
|
-
"There are no defined ",
|
|
202
|
-
props.experimentNameOverride,
|
|
203
|
-
"s"
|
|
204
|
-
] }) });
|
|
205
|
-
}, ExperimentItem = (props) => {
|
|
206
|
-
const { active } = props.value;
|
|
207
|
-
return active || props.inputProps.onChange(set(!0, ["active"])), props.renderDefault(props);
|
|
208
|
-
}, VariantInput = (props) => {
|
|
209
|
-
const experimentPath = props.path.slice(0, -2), defaultValue = useFormValue([...experimentPath, "default"]), handleClick = () => {
|
|
122
|
+
}, [actionProps, props.actions]), enhancedProps = useMemo(() => ({
|
|
123
|
+
...clearChildrenGroups(props),
|
|
124
|
+
actions: memoizedActions
|
|
125
|
+
}), [props, memoizedActions]);
|
|
126
|
+
return props.renderDefault(enhancedProps);
|
|
127
|
+
}, SegmentInput = (props) => {
|
|
128
|
+
const personalizationPath = props.path.slice(0, -2), defaultValue = useFormValue([...personalizationPath, "default"]), handleClick = () => {
|
|
210
129
|
props.onChange(set(defaultValue, ["value"]));
|
|
211
130
|
};
|
|
212
131
|
return /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
213
132
|
props.renderDefault(props),
|
|
214
133
|
/* @__PURE__ */ jsx(Inline, { space: 1, children: /* @__PURE__ */ jsx(Button, { text: "Copy default", mode: "ghost", onClick: () => handleClick() }) })
|
|
215
134
|
] });
|
|
216
|
-
},
|
|
217
|
-
const [subtitle, setSubtitle] = useState(void 0), [title, setTitle] = useState(void 0), [media, setMedia] = useState(void 0), client = useClient({ apiVersion: "2025-01-01" }), {
|
|
135
|
+
}, SegmentPreview = (props) => {
|
|
136
|
+
const [subtitle, setSubtitle] = useState(void 0), [title, setTitle] = useState(void 0), [media, setMedia] = useState(void 0), client = useClient({ apiVersion: "2025-01-01" }), { segments } = usePersonalizationContext(), { segment, value } = props, selectedSegment = segments.find((segmentItem) => segmentItem.id === segment);
|
|
218
137
|
useEffect(() => {
|
|
219
138
|
(async () => {
|
|
220
|
-
if (setTitle(`${
|
|
139
|
+
if (setTitle(`${selectedSegment?.label}`), typeof value == "string")
|
|
221
140
|
return setSubtitle(value);
|
|
222
141
|
if (isReference(value)) {
|
|
223
142
|
const doc = await client.getDocument(value._ref), referenceType = (props.schemaType.fields.find((field) => field.name === "value")?.type).to.find((field) => field.type?.name === doc?._type), selectFields = {}, previewFields = referenceType?.preview?.select || {};
|
|
@@ -230,7 +149,7 @@ const ArrayInput = (props) => {
|
|
|
230
149
|
}
|
|
231
150
|
return isImage(value) && setMedia(value), "";
|
|
232
151
|
})();
|
|
233
|
-
}, [value, client,
|
|
152
|
+
}, [value, client, selectedSegment?.label, props.schemaType]);
|
|
234
153
|
const previewProps = {
|
|
235
154
|
...props,
|
|
236
155
|
title,
|
|
@@ -238,65 +157,59 @@ const ArrayInput = (props) => {
|
|
|
238
157
|
media
|
|
239
158
|
};
|
|
240
159
|
return props.renderDefault(previewProps);
|
|
241
|
-
}
|
|
242
|
-
function flattenSchemaType(schemaType) {
|
|
243
|
-
return isDocumentSchemaType(schemaType) ? extractInnerFields(schemaType.fields, [], 5) : (console.error("Schema type is not a document"), []);
|
|
244
|
-
}
|
|
245
|
-
function extractInnerFields(fields, path, maxDepth) {
|
|
246
|
-
return path.length >= maxDepth ? [] : fields.reduce((acc, field) => {
|
|
247
|
-
const thisFieldWithPath = { path: [...path, field.name], ...field };
|
|
248
|
-
if (field.type.jsonType === "object") {
|
|
249
|
-
const innerFields = extractInnerFields(field.type.fields, [...path, field.name], maxDepth);
|
|
250
|
-
return [...acc, thisFieldWithPath, ...innerFields];
|
|
251
|
-
} else if (field.type.jsonType === "array") {
|
|
252
|
-
const innerFields = (field.type.of || []).reduce((arrayAcc, arrayType) => {
|
|
253
|
-
if ("fields" in arrayType) {
|
|
254
|
-
const typeFields = extractInnerFields(arrayType.fields, [...path, field.name], maxDepth);
|
|
255
|
-
return [...arrayAcc, ...typeFields];
|
|
256
|
-
}
|
|
257
|
-
return arrayAcc;
|
|
258
|
-
}, []);
|
|
259
|
-
return [...acc, thisFieldWithPath, ...innerFields];
|
|
260
|
-
}
|
|
261
|
-
return [...acc, thisFieldWithPath];
|
|
262
|
-
}, []);
|
|
263
|
-
}
|
|
264
|
-
const createExperimentType = ({
|
|
160
|
+
}, createPersonalizationType = ({
|
|
265
161
|
field,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
experimentId
|
|
162
|
+
personalizationNameOverride,
|
|
163
|
+
segmentNameOverride,
|
|
164
|
+
segmentId,
|
|
165
|
+
segmentArrayName
|
|
271
166
|
}) => {
|
|
272
|
-
const typeName = typeof field == "string" ? field : field.name, usedName = String(typeName[0]).toUpperCase() + String(typeName).slice(1),
|
|
167
|
+
const typeName = typeof field == "string" ? field : field.name, usedName = String(typeName[0]).toUpperCase() + String(typeName).slice(1), segmentName = `${segmentNameOverride}${usedName}`;
|
|
273
168
|
return defineType({
|
|
274
|
-
name: `${
|
|
169
|
+
name: `${personalizationNameOverride}${usedName}`,
|
|
275
170
|
type: "object",
|
|
171
|
+
groups: [
|
|
172
|
+
{
|
|
173
|
+
name: "default",
|
|
174
|
+
title: "Default",
|
|
175
|
+
hidden: ({ parent }) => !Array.isArray(parent)
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "personalization",
|
|
179
|
+
title: "Personalization options",
|
|
180
|
+
hidden: ({ parent }) => !Array.isArray(parent)
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "all-fields",
|
|
184
|
+
title: "All fields",
|
|
185
|
+
hidden: ({ parent }) => Array.isArray(parent)
|
|
186
|
+
}
|
|
187
|
+
],
|
|
276
188
|
components: {
|
|
277
189
|
field: (props) => /* @__PURE__ */ jsx(
|
|
278
|
-
|
|
190
|
+
Field,
|
|
279
191
|
{
|
|
280
192
|
...props,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
variantNameOverride
|
|
193
|
+
personalizationNameOverride,
|
|
194
|
+
segmentNameOverride
|
|
284
195
|
}
|
|
285
196
|
),
|
|
286
|
-
item:
|
|
197
|
+
item: ArrayItem
|
|
287
198
|
},
|
|
288
199
|
fields: [
|
|
289
200
|
typeof field == "string" ? (
|
|
290
201
|
// Define a simple field if all we have is the name as a string
|
|
291
202
|
defineField({
|
|
292
203
|
name: "default",
|
|
293
|
-
type: field
|
|
204
|
+
type: field,
|
|
205
|
+
group: "default"
|
|
294
206
|
})
|
|
295
207
|
) : (
|
|
296
208
|
// Pass in the configured options, but overwrite the name
|
|
297
209
|
{
|
|
298
210
|
...field,
|
|
299
|
-
name: "default"
|
|
211
|
+
name: "default",
|
|
212
|
+
group: "default"
|
|
300
213
|
}
|
|
301
214
|
),
|
|
302
215
|
defineField({
|
|
@@ -306,84 +219,54 @@ const createExperimentType = ({
|
|
|
306
219
|
initialValue: !1
|
|
307
220
|
}),
|
|
308
221
|
defineField({
|
|
309
|
-
name:
|
|
310
|
-
type: "string",
|
|
311
|
-
components: {
|
|
312
|
-
input: (props) => /* @__PURE__ */ jsx(
|
|
313
|
-
ExperimentInput,
|
|
314
|
-
{
|
|
315
|
-
...props,
|
|
316
|
-
experimentNameOverride,
|
|
317
|
-
variantNameOverride
|
|
318
|
-
}
|
|
319
|
-
)
|
|
320
|
-
},
|
|
321
|
-
hidden: ({ parent }) => !parent?.active
|
|
322
|
-
}),
|
|
323
|
-
defineField({
|
|
324
|
-
name: variantArrayName,
|
|
222
|
+
name: segmentArrayName,
|
|
325
223
|
type: "array",
|
|
326
|
-
hidden: ({ parent }) => !parent?.
|
|
224
|
+
hidden: ({ parent }) => !parent?.active,
|
|
225
|
+
group: "personalization",
|
|
327
226
|
components: {
|
|
328
|
-
input: (props) => /* @__PURE__ */ jsx(
|
|
329
|
-
ArrayInput,
|
|
330
|
-
{
|
|
331
|
-
...props,
|
|
332
|
-
variantName,
|
|
333
|
-
variantId,
|
|
334
|
-
experimentId
|
|
335
|
-
}
|
|
336
|
-
)
|
|
227
|
+
input: (props) => /* @__PURE__ */ jsx(ArrayInput, { ...props, segmentName, segmentId })
|
|
337
228
|
},
|
|
338
229
|
of: [
|
|
339
230
|
defineField({
|
|
340
|
-
name:
|
|
341
|
-
type:
|
|
231
|
+
name: segmentName,
|
|
232
|
+
type: segmentName
|
|
342
233
|
})
|
|
343
234
|
]
|
|
344
235
|
})
|
|
345
236
|
],
|
|
346
237
|
preview: {
|
|
347
238
|
select: {
|
|
348
|
-
base: "default"
|
|
349
|
-
experiment: experimentId
|
|
239
|
+
base: "default"
|
|
350
240
|
},
|
|
351
|
-
prepare: ({ base
|
|
352
|
-
const title = base?.title || base?.name || typeof base == "string" ? base : "",
|
|
241
|
+
prepare: ({ base }) => {
|
|
242
|
+
const title = base?.title || base?.name || typeof base == "string" ? base : "", media = base?.image || base?.photo || base?.media || "";
|
|
353
243
|
return {
|
|
354
|
-
title
|
|
355
|
-
subtitle: title ? experimentTitle : "",
|
|
244
|
+
title,
|
|
356
245
|
media
|
|
357
246
|
};
|
|
358
247
|
}
|
|
359
248
|
}
|
|
360
249
|
});
|
|
361
|
-
},
|
|
250
|
+
}, createSegmentType = ({
|
|
362
251
|
field,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
experimentId
|
|
252
|
+
segmentNameOverride,
|
|
253
|
+
segmentId
|
|
366
254
|
}) => {
|
|
367
255
|
const typeName = typeof field == "string" ? field : field.name, usedName = String(typeName[0]).toUpperCase() + String(typeName).slice(1);
|
|
368
256
|
return defineType({
|
|
369
|
-
name: `${
|
|
370
|
-
title: `${
|
|
257
|
+
name: `${segmentNameOverride}${usedName}`,
|
|
258
|
+
title: `${segmentNameOverride} array ${usedName}`,
|
|
371
259
|
type: "object",
|
|
372
260
|
components: {
|
|
373
|
-
preview:
|
|
374
|
-
input:
|
|
261
|
+
preview: SegmentPreview,
|
|
262
|
+
input: SegmentInput
|
|
375
263
|
},
|
|
376
264
|
fields: [
|
|
377
265
|
{
|
|
378
266
|
type: "string",
|
|
379
|
-
name:
|
|
267
|
+
name: segmentId,
|
|
380
268
|
readOnly: !0
|
|
381
269
|
},
|
|
382
|
-
{
|
|
383
|
-
type: "string",
|
|
384
|
-
name: experimentId,
|
|
385
|
-
hidden: !0
|
|
386
|
-
},
|
|
387
270
|
typeof field == "string" ? (
|
|
388
271
|
// Define a simple field if all we have is the name as a string
|
|
389
272
|
defineField({
|
|
@@ -402,71 +285,67 @@ const createExperimentType = ({
|
|
|
402
285
|
],
|
|
403
286
|
preview: {
|
|
404
287
|
select: {
|
|
405
|
-
|
|
406
|
-
experiment: experimentId,
|
|
288
|
+
segment: segmentId,
|
|
407
289
|
value: "value"
|
|
408
290
|
}
|
|
409
291
|
}
|
|
410
292
|
});
|
|
411
293
|
}, fieldSchema = ({
|
|
412
294
|
fields,
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
experimentId
|
|
295
|
+
personalizationNameOverride,
|
|
296
|
+
segmentNameOverride,
|
|
297
|
+
segmentId,
|
|
298
|
+
segmentArrayName
|
|
418
299
|
}) => [
|
|
300
|
+
...fields.map((field) => createSegmentType({ field, segmentNameOverride, segmentId })),
|
|
419
301
|
...fields.map(
|
|
420
|
-
(field) =>
|
|
421
|
-
),
|
|
422
|
-
...fields.map(
|
|
423
|
-
(field) => createExperimentType({
|
|
302
|
+
(field) => createPersonalizationType({
|
|
424
303
|
field,
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
experimentId
|
|
304
|
+
personalizationNameOverride,
|
|
305
|
+
segmentNameOverride,
|
|
306
|
+
segmentId,
|
|
307
|
+
segmentArrayName
|
|
430
308
|
})
|
|
431
309
|
)
|
|
432
|
-
],
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
|
|
310
|
+
], fieldLevelPersonalization = definePlugin(
|
|
311
|
+
(config) => {
|
|
312
|
+
const pluginConfig = { ...CONFIG_DEFAULT, ...config }, { fields, personalizationNameOverride, segmentNameOverride } = pluginConfig, segmentArrayName = `${segmentNameOverride}s`, segmentId = `${segmentNameOverride}Id`;
|
|
313
|
+
return {
|
|
314
|
+
name: "sanity-personalistaion-plugin-field-level-personalization",
|
|
315
|
+
schema: {
|
|
316
|
+
types: fieldSchema({
|
|
317
|
+
fields,
|
|
318
|
+
personalizationNameOverride,
|
|
319
|
+
segmentNameOverride,
|
|
320
|
+
segmentId,
|
|
321
|
+
segmentArrayName
|
|
322
|
+
})
|
|
323
|
+
},
|
|
324
|
+
form: {
|
|
325
|
+
components: {
|
|
326
|
+
input: (props) => {
|
|
327
|
+
if (!(props.id === "root" && isObjectInputProps(props)) || !flattenSchemaType(props.schemaType).some(
|
|
328
|
+
(field) => field.type.name.startsWith(personalizationNameOverride) || field.name.startsWith(personalizationNameOverride)
|
|
329
|
+
))
|
|
330
|
+
return props.renderDefault(props);
|
|
331
|
+
const providerProps = {
|
|
332
|
+
...props,
|
|
333
|
+
personalizationFieldPluginConfig: {
|
|
334
|
+
...pluginConfig,
|
|
335
|
+
segmentId,
|
|
336
|
+
segmentArrayName
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
return PersonalizationProvider(providerProps);
|
|
340
|
+
}
|
|
463
341
|
}
|
|
464
342
|
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
);
|
|
468
346
|
export {
|
|
469
347
|
fieldLevelExperiments,
|
|
348
|
+
fieldLevelPersonalization,
|
|
470
349
|
flattenSchemaType
|
|
471
350
|
};
|
|
472
351
|
//# sourceMappingURL=index.mjs.map
|