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