@uniformdev/context-ui 17.7.1-alpha.140 → 17.7.1-alpha.169

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/index.mjs CHANGED
@@ -1,4 +1,19 @@
1
- import{jsx as c}from"@emotion/react";import*as h from"react";import{InputComboBox as qe}from"@uniformdev/design-system";import{css as Ge}from"@emotion/react";import{jsx as He}from"@emotion/react/jsx-runtime";function N({op:e}){return He("div",{className:"operation-bubble",css:Ge`
1
+ // ../../scripts/emotion-jsx-shim.js
2
+ import { jsx } from "@emotion/react";
3
+ import * as React from "react";
4
+
5
+ // src/components/CriteriaOperatorMenu/CriteriaOperatorMenu.tsx
6
+ import { InputComboBox } from "@uniformdev/design-system";
7
+
8
+ // src/components/CriteriaOperatorMenu/OperatorBubble.tsx
9
+ import { css } from "@emotion/react";
10
+ import { jsx as jsx2 } from "@emotion/react/jsx-runtime";
11
+ function OperatorBubble({ op }) {
12
+ return /* @__PURE__ */ jsx2(
13
+ "div",
14
+ {
15
+ className: "operation-bubble",
16
+ css: css`
2
17
  align-items: center;
3
18
  background: var(--gray-700);
4
19
  border-radius: var(--rounded-full);
@@ -8,12 +23,661 @@ import{jsx as c}from"@emotion/react";import*as h from"react";import{InputComboBo
8
23
  height: 30px;
9
24
  justify-content: center;
10
25
  font-size: var(--fs-base);
11
- `,children:e})}import{jsx as K,jsxs as We}from"@emotion/react/jsx-runtime";var ue=e=>{var l,d;let{data:t,getStyles:o,isDisabled:a,innerRef:r,innerProps:n}=e,[s,i]=(d=(l=t.label)==null?void 0:l.split(":"))!=null?d:[];return We("div",{css:{...o("option",e),display:"flex",alignItems:"center",gap:"var(--spacing-sm)"},ref:r,"aria-disabled":a,...n,children:[i?K(N,{op:s}):K("div",{css:{width:"20px",height:"20px"}}),K("div",{children:i!=null?i:s})]})};import{jsx as ce}from"@emotion/react/jsx-runtime";var de=e=>{let{data:t,getStyles:o}=e;return ce("div",{css:{...o("singleValue",e),width:"max-content"},children:t.label.length===1?ce(N,{op:t.label}):t.label})};import{jsx as _e}from"@emotion/react/jsx-runtime";var fe=[{name:"=",description:"equals",value:"="},{name:"\u2260",description:"not equal",value:"!="},{name:">",description:"is greater than",value:">"},{name:"\u2265",description:"is greater than or equal to",value:">="},{name:"<",description:"is less than",value:"<"},{name:"\u2264",description:"is less than or equal to",value:"<="},{name:"has the strongest score",value:"+"},{name:"has the weakest score",value:"-"}];function ge({onChange:e,value:t,...o}){var a,r;return _e(qe,{...o,value:{label:(r=(a=fe.find(n=>n.value===t))==null?void 0:a.name)!=null?r:t,value:t},options:fe.map(n=>({label:n.description?`${n.name}:${n.description}`:n.name,value:n.value})),styles:{...o.styles,valueContainer:(n,s)=>{var i,l;return{...n,padding:"var(--spacing-sm)",...(l=(i=o.styles)==null?void 0:i.valueContainer)==null?void 0:l.call(i,n,s)}},menu:(n,s)=>{var i,l;return{...n,width:"max-content",...(l=(i=o.styles)==null?void 0:i.menu)==null?void 0:l.call(i,n,s)}},control:(n,s)=>{var i,l;return{...n,border:0,...(l=(i=o.styles)==null?void 0:i.control)==null?void 0:l.call(i,n,s)}},indicatorSeparator:(n,s)=>{var i,l;return{...n,display:"none",...(l=(i=o.styles)==null?void 0:i.indicatorSeparator)==null?void 0:l.call(i,n,s)}}},onChange:n=>{n&&e(n.value)},components:{SingleValue:de,Option:ue,...o.components}})}import{LoadingIndicator as tt}from"@uniformdev/design-system";import{createContext as nt,useContext as Y}from"react";import{ApiClientError as Fe,CachedManifestClient as je}from"@uniformdev/context/api";import{useEffect as Ke,useState as Ye}from"react";function z({apiHost:e,apiKey:t,projectId:o}){let[a,r]=Ye({loading:!1,notConfigured:!1,error:null,result:null});return Ke(()=>{if(!o||!t||!e){r({notConfigured:!0,loading:!1,error:null,result:null});return}(async()=>{r({notConfigured:!1,loading:!0,error:null,result:null});try{let i=await new je({projectId:o,apiKey:t,apiHost:e}).get({preview:!0});r({notConfigured:!1,loading:!1,error:null,result:i})}catch(s){let i;s instanceof Fe?(s.statusCode===403&&(i=`The API key ${t} did not have permissions to fetch the manifest. Ensure Context > Read Drafts permissions are granted.`),i=s.message):i=s.toString(),r({notConfigured:!1,loading:!1,error:i,result:null});return}})()},[e,t,o]),{result:a.result,error:a.error,loading:a.loading,notConfigured:a.notConfigured}}import{ApiClientError as Xe,CachedDimensionClient as Je,computeDimensionDisplayName as Qe}from"@uniformdev/context/api";import{useEffect as Ze,useState as et}from"react";function Ce(e,t,o){return e.reduce((a,r)=>{let n=t(r);if(typeof n=="undefined"||n===null)throw new Error("Objectify key selector returned undefined or null.");return a[t(r)]=o?o(r):r,a},{})}function V({apiHost:e,apiKey:t,projectId:o}){let[a,r]=et({loading:!1,notConfigured:!1,error:null,result:null});return Ze(()=>{if(!o||!t||!e){r({notConfigured:!0,loading:!1,error:null,result:null});return}(async()=>{r({notConfigured:!1,loading:!0,error:null,result:null});try{let i=(await new Je({projectId:o,apiKey:t,apiHost:e}).get()).dimensions.map(d=>({...d,displayName:Qe(d)})),l={dimensions:i,dimIndex:Ce(i,d=>d.dim,d=>d)};r({notConfigured:!1,loading:!1,error:null,result:l})}catch(s){let i;s instanceof Xe?i=s.message:i=s.toString(),r({notConfigured:!1,loading:!1,error:i,result:null});return}})()},[e,t,o]),{result:a.result,error:a.error,loading:a.loading,notConfigured:a.notConfigured}}import{Fragment as he,jsx as E}from"@emotion/react/jsx-runtime";var L=nt(null),$n=({loadingComponent:e,errorComponent:t,contextConfig:o,children:a})=>{let r=z(o),n=V(o);return r.error||r.notConfigured?t?E(t,{contextConfig:o,result:r}):E(he,{children:"ErrorComponent is not configured"}):n.error||n.notConfigured?t?E(t,{contextConfig:o,result:n}):E(he,{children:"ErrorComponent is not configured"}):r.loading||n.loading?e?E(e,{}):E(tt,{}):E(L.Provider,{value:{manifest:r.result,dimensions:n.result,contextConfig:o},children:a})};function An(){let e=Y(L);if(!(e!=null&&e.contextConfig))throw new Error("Not within DataContext! Configuration data is not exist.");return e.contextConfig}function Un(){let e=Y(L);if(!(e!=null&&e.manifest))throw new Error("Not within DataContext! Manifest data is not exist.");return e.manifest}function Gn(){let e=Y(L);if(!(e!=null&&e.dimensions))throw new Error("Not within DataContext! Dimensions data is not exist.");return e.dimensions}import{InputComboBox as lt}from"@uniformdev/design-system";import{useState as mt}from"react";import{Icon as ot}from"@uniformdev/design-system";function X(e){return{label:e.displayName,value:e.dim,isDisabled:!1}}function $(e){if(!e)return"unavailable";let[t]=e.split(":");switch(t.toLowerCase()){case"signal":return"data";case"intent":return"assign";case"audience":return"boy";default:return"user-list"}}function A(e){let t=[],o="";for(let a of e){let[r]=a.displayName.split(":");o!==r&&(t.push({label:r,options:[]}),o=r),t[t.length-1].options.push(X(a))}return t}import{jsx as J,jsxs as rt}from"@emotion/react/jsx-runtime";var U=e=>{var r;let{data:t,getStyles:o,className:a}=e;return J("div",{css:{...o("groupHeading",e),textTransform:"none",fontSize:"var(--font-size-sm)"},className:a,children:rt("small",{css:{color:"var(--gray-500)",display:"flex",alignItems:"center",gap:"var(--spacing-xs)"},children:[J(ot,{icon:$((r=t.label)!=null?r:""),iconColor:"currentColor",size:16}),J("span",{children:t.label})]})})};import{css as it}from"@emotion/react";import{jsx as at}from"@emotion/react/jsx-runtime";function G({message:e}){return e?at("div",{css:it`
26
+ `,
27
+ children: op
28
+ }
29
+ );
30
+ }
31
+
32
+ // src/components/CriteriaOperatorMenu/CriteriaOperatorOption.tsx
33
+ import { jsx as jsx3, jsxs } from "@emotion/react/jsx-runtime";
34
+ var CriteriaOperatorOption = (props) => {
35
+ var _a, _b;
36
+ const { data, getStyles, isDisabled, innerRef, innerProps } = props;
37
+ const [name, description] = (_b = (_a = data.label) == null ? void 0 : _a.split(":")) != null ? _b : [];
38
+ return /* @__PURE__ */ jsxs(
39
+ "div",
40
+ {
41
+ css: {
42
+ ...getStyles("option", props),
43
+ display: "flex",
44
+ alignItems: "center",
45
+ gap: "var(--spacing-sm)"
46
+ },
47
+ ref: innerRef,
48
+ "aria-disabled": isDisabled,
49
+ ...innerProps,
50
+ children: [
51
+ description ? /* @__PURE__ */ jsx3(OperatorBubble, { op: name }) : /* @__PURE__ */ jsx3(
52
+ "div",
53
+ {
54
+ css: {
55
+ width: "20px",
56
+ height: "20px"
57
+ }
58
+ }
59
+ ),
60
+ /* @__PURE__ */ jsx3("div", { children: description != null ? description : name })
61
+ ]
62
+ }
63
+ );
64
+ };
65
+
66
+ // src/components/CriteriaOperatorMenu/CriteriaOperatorSingleValue.tsx
67
+ import { jsx as jsx4 } from "@emotion/react/jsx-runtime";
68
+ var CriteriaOperatorSingleValue = (props) => {
69
+ const { data, getStyles } = props;
70
+ return /* @__PURE__ */ jsx4(
71
+ "div",
72
+ {
73
+ css: {
74
+ ...getStyles("singleValue", props),
75
+ width: "max-content"
76
+ },
77
+ children: data.label.length === 1 ? /* @__PURE__ */ jsx4(OperatorBubble, { op: data.label }) : data.label
78
+ }
79
+ );
80
+ };
81
+
82
+ // src/components/CriteriaOperatorMenu/CriteriaOperatorMenu.tsx
83
+ import { jsx as jsx5 } from "@emotion/react/jsx-runtime";
84
+ var contextCriteriaMenuOperators = [
85
+ {
86
+ name: "=",
87
+ description: "equals",
88
+ value: "="
89
+ },
90
+ {
91
+ name: "\u2260",
92
+ description: "not equal",
93
+ value: "!="
94
+ },
95
+ {
96
+ name: ">",
97
+ description: "is greater than",
98
+ value: ">"
99
+ },
100
+ {
101
+ name: "\u2265",
102
+ description: "is greater than or equal to",
103
+ value: ">="
104
+ },
105
+ {
106
+ name: "<",
107
+ description: "is less than",
108
+ value: "<"
109
+ },
110
+ {
111
+ name: "\u2264",
112
+ description: "is less than or equal to",
113
+ value: "<="
114
+ },
115
+ {
116
+ name: "has the strongest score",
117
+ value: "+"
118
+ },
119
+ {
120
+ name: "has the weakest score",
121
+ value: "-"
122
+ }
123
+ ];
124
+ function CriteriaOperatorMenu({ onChange, value, ...props }) {
125
+ var _a, _b;
126
+ return /* @__PURE__ */ jsx5(
127
+ InputComboBox,
128
+ {
129
+ ...props,
130
+ value: {
131
+ label: (_b = (_a = contextCriteriaMenuOperators.find((e) => e.value === value)) == null ? void 0 : _a.name) != null ? _b : value,
132
+ value
133
+ },
134
+ options: contextCriteriaMenuOperators.map((option) => ({
135
+ label: option.description ? `${option.name}:${option.description}` : option.name,
136
+ value: option.value
137
+ })),
138
+ styles: {
139
+ ...props.styles,
140
+ valueContainer: (provided, state) => {
141
+ var _a2, _b2;
142
+ return {
143
+ ...provided,
144
+ padding: "var(--spacing-sm)",
145
+ ...(_b2 = (_a2 = props.styles) == null ? void 0 : _a2.valueContainer) == null ? void 0 : _b2.call(_a2, provided, state)
146
+ };
147
+ },
148
+ menu: (provided, state) => {
149
+ var _a2, _b2;
150
+ return {
151
+ ...provided,
152
+ width: "max-content",
153
+ ...(_b2 = (_a2 = props.styles) == null ? void 0 : _a2.menu) == null ? void 0 : _b2.call(_a2, provided, state)
154
+ };
155
+ },
156
+ control: (provided, state) => {
157
+ var _a2, _b2;
158
+ return {
159
+ ...provided,
160
+ border: 0,
161
+ ...(_b2 = (_a2 = props.styles) == null ? void 0 : _a2.control) == null ? void 0 : _b2.call(_a2, provided, state)
162
+ };
163
+ },
164
+ indicatorSeparator: (provided, state) => {
165
+ var _a2, _b2;
166
+ return {
167
+ ...provided,
168
+ display: "none",
169
+ ...(_b2 = (_a2 = props.styles) == null ? void 0 : _a2.indicatorSeparator) == null ? void 0 : _b2.call(_a2, provided, state)
170
+ };
171
+ }
172
+ },
173
+ onChange: (e) => {
174
+ if (e) {
175
+ onChange(e.value);
176
+ }
177
+ },
178
+ components: {
179
+ SingleValue: CriteriaOperatorSingleValue,
180
+ Option: CriteriaOperatorOption,
181
+ ...props.components
182
+ }
183
+ }
184
+ );
185
+ }
186
+
187
+ // src/components/DataContext/DataContext.tsx
188
+ import { LoadingIndicator } from "@uniformdev/design-system";
189
+ import { createContext, useContext } from "react";
190
+
191
+ // src/hooks/useContextData.ts
192
+ import { ApiClientError, CachedManifestClient } from "@uniformdev/context/api";
193
+ import { useEffect, useState } from "react";
194
+ function useContextData({ apiHost, apiKey, projectId }) {
195
+ const [state, setState] = useState({
196
+ loading: false,
197
+ notConfigured: false,
198
+ error: null,
199
+ result: null
200
+ });
201
+ useEffect(() => {
202
+ if (!projectId || !apiKey || !apiHost) {
203
+ setState({ notConfigured: true, loading: false, error: null, result: null });
204
+ return;
205
+ }
206
+ const runEffect = async () => {
207
+ setState({ notConfigured: false, loading: true, error: null, result: null });
208
+ try {
209
+ const client = new CachedManifestClient({
210
+ projectId,
211
+ apiKey,
212
+ apiHost
213
+ });
214
+ const result = await client.get({ preview: true });
215
+ setState({ notConfigured: false, loading: false, error: null, result });
216
+ } catch (e) {
217
+ let message;
218
+ if (e instanceof ApiClientError) {
219
+ if (e.statusCode === 403) {
220
+ message = `The API key ${apiKey} did not have permissions to fetch the manifest. Ensure Context > Read Drafts permissions are granted.`;
221
+ }
222
+ message = e.message;
223
+ } else {
224
+ message = e.toString();
225
+ }
226
+ setState({ notConfigured: false, loading: false, error: message, result: null });
227
+ return;
228
+ }
229
+ };
230
+ runEffect();
231
+ }, [apiHost, apiKey, projectId]);
232
+ return {
233
+ result: state.result,
234
+ error: state.error,
235
+ loading: state.loading,
236
+ notConfigured: state.notConfigured
237
+ };
238
+ }
239
+
240
+ // src/hooks/useDimensions.ts
241
+ import { ApiClientError as ApiClientError2, CachedDimensionClient, computeDimensionDisplayName } from "@uniformdev/context/api";
242
+ import { useEffect as useEffect2, useState as useState2 } from "react";
243
+
244
+ // src/utils/objectify.ts
245
+ function objectify(array2, keySelector, valueSelector) {
246
+ return array2.reduce((prev, current) => {
247
+ const key = keySelector(current);
248
+ if (typeof key === "undefined" || key === null) {
249
+ throw new Error(`Objectify key selector returned undefined or null.`);
250
+ }
251
+ prev[keySelector(current)] = valueSelector ? valueSelector(current) : current;
252
+ return prev;
253
+ }, {});
254
+ }
255
+
256
+ // src/hooks/useDimensions.ts
257
+ function useDimensions({ apiHost, apiKey, projectId }) {
258
+ const [state, setState] = useState2({
259
+ loading: false,
260
+ notConfigured: false,
261
+ error: null,
262
+ result: null
263
+ });
264
+ useEffect2(() => {
265
+ if (!projectId || !apiKey || !apiHost) {
266
+ setState({ notConfigured: true, loading: false, error: null, result: null });
267
+ return;
268
+ }
269
+ const runEffect = async () => {
270
+ setState({ notConfigured: false, loading: true, error: null, result: null });
271
+ try {
272
+ const client = new CachedDimensionClient({
273
+ projectId,
274
+ apiKey,
275
+ apiHost
276
+ });
277
+ const dimensions = (await client.get()).dimensions.map((dim) => ({
278
+ ...dim,
279
+ displayName: computeDimensionDisplayName(dim)
280
+ }));
281
+ const result = {
282
+ dimensions,
283
+ dimIndex: objectify(
284
+ dimensions,
285
+ (k) => k.dim,
286
+ (v) => v
287
+ )
288
+ };
289
+ setState({ notConfigured: false, loading: false, error: null, result });
290
+ } catch (e) {
291
+ let message;
292
+ if (e instanceof ApiClientError2) {
293
+ message = e.message;
294
+ } else {
295
+ message = e.toString();
296
+ }
297
+ setState({ notConfigured: false, loading: false, error: message, result: null });
298
+ return;
299
+ }
300
+ };
301
+ runEffect();
302
+ }, [apiHost, apiKey, projectId]);
303
+ return {
304
+ result: state.result,
305
+ error: state.error,
306
+ loading: state.loading,
307
+ notConfigured: state.notConfigured
308
+ };
309
+ }
310
+
311
+ // src/components/DataContext/DataContext.tsx
312
+ import { Fragment, jsx as jsx6 } from "@emotion/react/jsx-runtime";
313
+ var ContextDataContext = createContext(null);
314
+ var ContextData = ({
315
+ loadingComponent: LoadingComponent,
316
+ errorComponent: ErrorComponent,
317
+ contextConfig,
318
+ children
319
+ }) => {
320
+ const contextData = useContextData(contextConfig);
321
+ const dimensionsData = useDimensions(contextConfig);
322
+ if (contextData.error || contextData.notConfigured) {
323
+ if (ErrorComponent)
324
+ return /* @__PURE__ */ jsx6(ErrorComponent, { contextConfig, result: contextData });
325
+ else
326
+ return /* @__PURE__ */ jsx6(Fragment, { children: "ErrorComponent is not configured" });
327
+ }
328
+ if (dimensionsData.error || dimensionsData.notConfigured) {
329
+ if (ErrorComponent)
330
+ return /* @__PURE__ */ jsx6(ErrorComponent, { contextConfig, result: dimensionsData });
331
+ else
332
+ return /* @__PURE__ */ jsx6(Fragment, { children: "ErrorComponent is not configured" });
333
+ }
334
+ if (contextData.loading || dimensionsData.loading) {
335
+ if (LoadingComponent)
336
+ return /* @__PURE__ */ jsx6(LoadingComponent, {});
337
+ else
338
+ return /* @__PURE__ */ jsx6(LoadingIndicator, {});
339
+ }
340
+ return /* @__PURE__ */ jsx6(
341
+ ContextDataContext.Provider,
342
+ {
343
+ value: { manifest: contextData.result, dimensions: dimensionsData.result, contextConfig },
344
+ children
345
+ }
346
+ );
347
+ };
348
+ function useContextConfig() {
349
+ const context = useContext(ContextDataContext);
350
+ if (!(context == null ? void 0 : context.contextConfig)) {
351
+ throw new Error("Not within DataContext! Configuration data is not exist.");
352
+ }
353
+ return context.contextConfig;
354
+ }
355
+ function useManifest() {
356
+ const context = useContext(ContextDataContext);
357
+ if (!(context == null ? void 0 : context.manifest)) {
358
+ throw new Error("Not within DataContext! Manifest data is not exist.");
359
+ }
360
+ return context.manifest;
361
+ }
362
+ function useDimensionsDataContext() {
363
+ const context = useContext(ContextDataContext);
364
+ if (!(context == null ? void 0 : context.dimensions)) {
365
+ throw new Error("Not within DataContext! Dimensions data is not exist.");
366
+ }
367
+ return context.dimensions;
368
+ }
369
+
370
+ // src/components/DimensionMenu/CriteriaMatchMenu.tsx
371
+ import { InputComboBox as InputComboBox3 } from "@uniformdev/design-system";
372
+ import { useState as useState3 } from "react";
373
+
374
+ // src/components/DimensionMenu/DimensionGroupHeading.tsx
375
+ import { Icon } from "@uniformdev/design-system";
376
+
377
+ // src/components/DimensionMenu/utils.ts
378
+ function dimensionToMenuOption(dimension) {
379
+ return {
380
+ label: dimension.displayName,
381
+ value: dimension.dim,
382
+ isDisabled: false
383
+ };
384
+ }
385
+ function dimensionIcon(displayName) {
386
+ if (!displayName) {
387
+ return "unavailable";
388
+ }
389
+ const [type] = displayName.split(":");
390
+ switch (type.toLowerCase()) {
391
+ case "signal":
392
+ return "data";
393
+ case "intent":
394
+ return "assign";
395
+ case "audience":
396
+ return "boy";
397
+ default:
398
+ return "user-list";
399
+ }
400
+ }
401
+ function groupDimensions(dimensions) {
402
+ const result = [];
403
+ let lastType = "";
404
+ for (const dim of dimensions) {
405
+ const [type] = dim.displayName.split(":");
406
+ if (lastType !== type) {
407
+ result.push({ label: type, options: [] });
408
+ lastType = type;
409
+ }
410
+ result[result.length - 1].options.push(dimensionToMenuOption(dim));
411
+ }
412
+ return result;
413
+ }
414
+
415
+ // src/components/DimensionMenu/DimensionGroupHeading.tsx
416
+ import { jsx as jsx7, jsxs as jsxs2 } from "@emotion/react/jsx-runtime";
417
+ var DimensionGroupHeading = (props) => {
418
+ var _a;
419
+ const { data, getStyles, className } = props;
420
+ return /* @__PURE__ */ jsx7(
421
+ "div",
422
+ {
423
+ css: {
424
+ ...getStyles("groupHeading", props),
425
+ textTransform: "none",
426
+ fontSize: "var(--font-size-sm)"
427
+ },
428
+ className,
429
+ children: /* @__PURE__ */ jsxs2(
430
+ "small",
431
+ {
432
+ css: { color: "var(--gray-500)", display: "flex", alignItems: "center", gap: "var(--spacing-xs)" },
433
+ children: [
434
+ /* @__PURE__ */ jsx7(Icon, { icon: dimensionIcon((_a = data.label) != null ? _a : ""), iconColor: "currentColor", size: 16 }),
435
+ /* @__PURE__ */ jsx7("span", { children: data.label })
436
+ ]
437
+ }
438
+ )
439
+ }
440
+ );
441
+ };
442
+
443
+ // src/components/DimensionMenu/DimensionMenuErrorMessage.tsx
444
+ import { css as css2 } from "@emotion/react";
445
+ import { jsx as jsx8 } from "@emotion/react/jsx-runtime";
446
+ function DimensionMenuErrorMessage({ message }) {
447
+ if (!message)
448
+ return null;
449
+ return /* @__PURE__ */ jsx8(
450
+ "div",
451
+ {
452
+ css: css2`
12
453
  color: var(--brand-primary-2);
13
454
  font-size: var(--fs-xs);
14
455
  position: absolute;
15
456
  bottom: calc((var(--spacing-base) * -1) + -2px);
16
- `,children:e}):null}import{jsx as be}from"@emotion/react/jsx-runtime";var H=e=>{var p,m;let{data:t,getStyles:o,cx:a,isDisabled:r,isFocused:n,isSelected:s,className:i,innerRef:l,innerProps:d}=e,[,C]=(m=(p=t.label)==null?void 0:p.split(":"))!=null?m:[];return be("div",{css:o("option",e),className:a({option:!0,"option--is-disabled":r,"option--is-focused":n,"option--is-selected":s},i),ref:l,"aria-disabled":r,...d,children:be("div",{css:{color:"var(--gray-700)"},children:C!=null?C:t.label})})};import{Icon as st}from"@uniformdev/design-system";import{jsx as Q,jsxs as ve}from"@emotion/react/jsx-runtime";function ye({displayName:e}){let[t,o]=e.split(":");return ve("div",{css:{whiteSpace:"normal",overflow:"hidden"},children:[o?ve("small",{css:{color:"var(--gray-500)",display:"flex",alignItems:"center",gap:"var(--spacing-xs)"},children:[t?Q(st,{icon:$(t),iconColor:"currentColor",size:16}):null,Q("span",{"data-test-id":"dimension-name",children:t})]}):null,Q("div",{css:{color:"var(--gray-700)"},"data-test-id":"dimension-value",children:o!=null?o:t})]})}import{jsx as xe}from"@emotion/react/jsx-runtime";var W=e=>{let{data:t,getStyles:o}=e;return xe("div",{css:o("singleValue",e),children:xe(ye,{displayName:t.label})})};import{Fragment as Z,jsx as _,jsxs as B}from"@emotion/react/jsx-runtime";function De({onChange:e,criteriaMatch:t,dimensions:o,errorMessage:a,...r}){var d,C;let[n,s]=mt(typeof t.r!="undefined"&&q(t.r)!==null?t.r.toString(10):""),i=t.rDim,l=t.rDim?o.dimIndex[t.rDim]:void 0;return B(Z,{children:[_(lt,{...r,inputValue:n,menuShouldScrollIntoView:!0,value:{label:(d=l==null?void 0:l.displayName)!=null?d:i&&!l?`${t.rDim} (unknown)`:"",value:(C=t.rDim)!=null?C:t.r?t.r.toString(10):"",isDisabled:!1},options:[{label:"Enter a numeric score to match, or choose another dimension to match its score",value:"",isDisabled:!0},...A(o.dimensions)],styles:{...r.styles,valueContainer:(p,m)=>{var f,w;return{...p,padding:"var(--spacing-sm)",...(w=(f=r.styles)==null?void 0:f.valueContainer)==null?void 0:w.call(f,p,m)}},option:(p,m)=>{var f,w;return{fontSize:m.isDisabled?"0.8rem":void 0,...(w=(f=r.styles)==null?void 0:f.option)==null?void 0:w.call(f,p,m)}}},onChange:p=>{var m;p&&(e({...t,rDim:(m=p.value)==null?void 0:m.toString(),r:void 0}),s(""))},onInputChange:(p,m)=>{let f=q(p);m.action==="input-change"||m.action==="set-value"?(s(p),(f||p==="")&&e({...t,r:p||void 0,rDim:void 0})):!f&&!q(m.prevInputValue)&&(!p&&t.r?s(t.r.toString()):s(p))},components:{...r.components,Option:H,SingleValue:W,GroupHeading:U},noOptionsMessage:({inputValue:p})=>q(p)?B(Z,{children:[B("div",{children:["Score: ",p]}),_("small",{children:"If you want to match on another dimension\u2019s score instead, clear the score value to search for a dimension."})]}):B(Z,{children:[B("div",{children:["No dimensions match your search \u201C",p,"\u201D"]}),_("small",{children:"If you want to match a literal score, enter a numeric value."})]})}),_(G,{message:a})]})}function q(e){return/^\d+$/.test(e.toString(10))}import{InputComboBox as pt}from"@uniformdev/design-system";import{Fragment as ut,jsx as Ie,jsxs as ct}from"@emotion/react/jsx-runtime";function we({onChange:e,value:t,dimensions:o,errorMessage:a,...r}){return ct(ut,{children:[Ie(pt,{...r,value:t?X(t):void 0,options:A(o),styles:{...r.styles,valueContainer:(n,s)=>{var i,l;return{...n,padding:"var(--spacing-sm)",...(l=(i=r.styles)==null?void 0:i.valueContainer)==null?void 0:l.call(i,n,s)}}},onChange:n=>{n&&e(o.find(s=>s.dim===n.value))},components:{Option:H,SingleValue:W,GroupHeading:U,...r.components}}),Ie(G,{message:a})]})}import{Icon as gt}from"@uniformdev/design-system";import{CgChevronRight as Ct}from"react-icons/cg";import{css as dt}from"@emotion/react";var Re=dt`
457
+ `,
458
+ children: message
459
+ }
460
+ );
461
+ }
462
+
463
+ // src/components/DimensionMenu/DimensionOption.tsx
464
+ import { jsx as jsx9 } from "@emotion/react/jsx-runtime";
465
+ var DimensionOption = (props) => {
466
+ var _a, _b;
467
+ const { data, getStyles, cx, isDisabled, isFocused, isSelected, className, innerRef, innerProps } = props;
468
+ const [, value] = (_b = (_a = data.label) == null ? void 0 : _a.split(":")) != null ? _b : [];
469
+ return /* @__PURE__ */ jsx9(
470
+ "div",
471
+ {
472
+ css: getStyles("option", props),
473
+ className: cx(
474
+ {
475
+ option: true,
476
+ "option--is-disabled": isDisabled,
477
+ "option--is-focused": isFocused,
478
+ "option--is-selected": isSelected
479
+ },
480
+ className
481
+ ),
482
+ ref: innerRef,
483
+ "aria-disabled": isDisabled,
484
+ ...innerProps,
485
+ children: /* @__PURE__ */ jsx9("div", { css: { color: "var(--gray-700)" }, children: value != null ? value : data.label })
486
+ }
487
+ );
488
+ };
489
+
490
+ // src/components/DimensionMenu/DimensionValue.tsx
491
+ import { Icon as Icon2 } from "@uniformdev/design-system";
492
+ import { jsx as jsx10, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
493
+ function DimensionValue({ displayName }) {
494
+ const [type, name] = displayName.split(":");
495
+ return /* @__PURE__ */ jsxs3(
496
+ "div",
497
+ {
498
+ css: {
499
+ whiteSpace: "normal",
500
+ overflow: "hidden"
501
+ },
502
+ children: [
503
+ name ? /* @__PURE__ */ jsxs3(
504
+ "small",
505
+ {
506
+ css: { color: "var(--gray-500)", display: "flex", alignItems: "center", gap: "var(--spacing-xs)" },
507
+ children: [
508
+ type ? /* @__PURE__ */ jsx10(Icon2, { icon: dimensionIcon(type), iconColor: "currentColor", size: 16 }) : null,
509
+ /* @__PURE__ */ jsx10("span", { "data-test-id": "dimension-name", children: type })
510
+ ]
511
+ }
512
+ ) : null,
513
+ /* @__PURE__ */ jsx10("div", { css: { color: "var(--gray-700)" }, "data-test-id": "dimension-value", children: name != null ? name : type })
514
+ ]
515
+ }
516
+ );
517
+ }
518
+
519
+ // src/components/DimensionMenu/DimensionSingleValue.tsx
520
+ import { jsx as jsx11 } from "@emotion/react/jsx-runtime";
521
+ var DimensionSingleValue = (props) => {
522
+ const { data, getStyles } = props;
523
+ return /* @__PURE__ */ jsx11("div", { css: getStyles("singleValue", props), children: /* @__PURE__ */ jsx11(DimensionValue, { displayName: data.label }) });
524
+ };
525
+
526
+ // src/components/DimensionMenu/CriteriaMatchMenu.tsx
527
+ import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
528
+ function CriteriaMatchMenu({
529
+ onChange,
530
+ criteriaMatch,
531
+ dimensions,
532
+ errorMessage,
533
+ ...props
534
+ }) {
535
+ var _a, _b;
536
+ const [inputValue, setInputValue] = useState3(
537
+ typeof criteriaMatch.r !== "undefined" && isInt(criteriaMatch.r) !== null ? criteriaMatch.r.toString(10) : ""
538
+ );
539
+ const rDim = criteriaMatch.rDim;
540
+ const targetDim = criteriaMatch.rDim ? dimensions.dimIndex[criteriaMatch.rDim] : void 0;
541
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
542
+ /* @__PURE__ */ jsx12(
543
+ InputComboBox3,
544
+ {
545
+ ...props,
546
+ inputValue,
547
+ menuShouldScrollIntoView: true,
548
+ value: {
549
+ label: (_a = targetDim == null ? void 0 : targetDim.displayName) != null ? _a : rDim && !targetDim ? `${criteriaMatch.rDim} (unknown)` : "",
550
+ value: (_b = criteriaMatch.rDim) != null ? _b : criteriaMatch.r ? criteriaMatch.r.toString(10) : "",
551
+ isDisabled: false
552
+ },
553
+ options: [
554
+ {
555
+ label: "Enter a numeric score to match, or choose another dimension to match its score",
556
+ value: "",
557
+ isDisabled: true
558
+ },
559
+ ...groupDimensions(dimensions.dimensions)
560
+ ],
561
+ styles: {
562
+ ...props.styles,
563
+ valueContainer: (provided, state) => {
564
+ var _a2, _b2;
565
+ return {
566
+ ...provided,
567
+ padding: "var(--spacing-sm)",
568
+ ...(_b2 = (_a2 = props.styles) == null ? void 0 : _a2.valueContainer) == null ? void 0 : _b2.call(_a2, provided, state)
569
+ };
570
+ },
571
+ option: (provided, state) => {
572
+ var _a2, _b2;
573
+ return {
574
+ fontSize: state.isDisabled ? "0.8rem" : void 0,
575
+ ...(_b2 = (_a2 = props.styles) == null ? void 0 : _a2.option) == null ? void 0 : _b2.call(_a2, provided, state)
576
+ };
577
+ }
578
+ },
579
+ onChange: (e) => {
580
+ var _a2;
581
+ if (e) {
582
+ onChange({ ...criteriaMatch, rDim: (_a2 = e.value) == null ? void 0 : _a2.toString(), r: void 0 });
583
+ setInputValue("");
584
+ }
585
+ },
586
+ onInputChange: (newValue, meta) => {
587
+ const isValueInt = isInt(newValue);
588
+ if (meta.action === "input-change" || meta.action === "set-value") {
589
+ setInputValue(newValue);
590
+ if (isValueInt || newValue === "") {
591
+ onChange({ ...criteriaMatch, r: newValue || void 0, rDim: void 0 });
592
+ }
593
+ } else if (!isValueInt && !isInt(meta.prevInputValue)) {
594
+ if (!newValue && criteriaMatch.r) {
595
+ setInputValue(criteriaMatch.r.toString());
596
+ } else {
597
+ setInputValue(newValue);
598
+ }
599
+ }
600
+ },
601
+ components: {
602
+ ...props.components,
603
+ Option: DimensionOption,
604
+ SingleValue: DimensionSingleValue,
605
+ GroupHeading: DimensionGroupHeading
606
+ },
607
+ noOptionsMessage: ({ inputValue: inputValue2 }) => {
608
+ if (isInt(inputValue2)) {
609
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
610
+ /* @__PURE__ */ jsxs4("div", { children: [
611
+ "Score: ",
612
+ inputValue2
613
+ ] }),
614
+ /* @__PURE__ */ jsx12("small", { children: "If you want to match on another dimension\u2019s score instead, clear the score value to search for a dimension." })
615
+ ] });
616
+ }
617
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
618
+ /* @__PURE__ */ jsxs4("div", { children: [
619
+ "No dimensions match your search \u201C",
620
+ inputValue2,
621
+ "\u201D"
622
+ ] }),
623
+ /* @__PURE__ */ jsx12("small", { children: "If you want to match a literal score, enter a numeric value." })
624
+ ] });
625
+ }
626
+ }
627
+ ),
628
+ /* @__PURE__ */ jsx12(DimensionMenuErrorMessage, { message: errorMessage })
629
+ ] });
630
+ }
631
+ function isInt(value) {
632
+ return /^\d+$/.test(value.toString(10));
633
+ }
634
+
635
+ // src/components/DimensionMenu/DimensionMenu.tsx
636
+ import { InputComboBox as InputComboBox4 } from "@uniformdev/design-system";
637
+ import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
638
+ function DimensionMenu({ onChange, value, dimensions, errorMessage, ...props }) {
639
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
640
+ /* @__PURE__ */ jsx13(
641
+ InputComboBox4,
642
+ {
643
+ ...props,
644
+ value: value ? dimensionToMenuOption(value) : void 0,
645
+ options: groupDimensions(dimensions),
646
+ styles: {
647
+ ...props.styles,
648
+ valueContainer: (provided, state) => {
649
+ var _a, _b;
650
+ return {
651
+ ...provided,
652
+ padding: "var(--spacing-sm)",
653
+ ...(_b = (_a = props.styles) == null ? void 0 : _a.valueContainer) == null ? void 0 : _b.call(_a, provided, state)
654
+ };
655
+ }
656
+ },
657
+ onChange: (e) => {
658
+ if (e) {
659
+ onChange(dimensions.find((d) => d.dim === e.value));
660
+ }
661
+ },
662
+ components: {
663
+ Option: DimensionOption,
664
+ SingleValue: DimensionSingleValue,
665
+ GroupHeading: DimensionGroupHeading,
666
+ ...props.components
667
+ }
668
+ }
669
+ ),
670
+ /* @__PURE__ */ jsx13(DimensionMenuErrorMessage, { message: errorMessage })
671
+ ] });
672
+ }
673
+
674
+ // src/components/EditLink/EditLink.tsx
675
+ import { Icon as Icon3 } from "@uniformdev/design-system";
676
+ import { CgChevronRight } from "react-icons/cg";
677
+
678
+ // src/components/EditLink/EditLink.styles.ts
679
+ import { css as css3 } from "@emotion/react";
680
+ var editLink = css3`
17
681
  display: flex;
18
682
  align-items: center;
19
683
  font-weight: var(--fw-bold);
@@ -24,7 +688,44 @@ import{jsx as c}from"@emotion/react";import*as h from"react";import{InputComboBo
24
688
  &:focus {
25
689
  text-decoration-line: underline;
26
690
  }
27
- `;import{jsx as ht,jsxs as bt}from"@emotion/react/jsx-runtime";var Me=({linkTo:e,name:t,linkText:o=`Edit ${t} Component`})=>bt("a",{css:Re,title:`Edit ${t} component definition`,rel:"noopener noreferrer",target:"_blank",href:e,children:[o,ht(gt,{icon:Ct,iconColor:"currentColor",size:"1.5rem"})]});import{css as re}from"@emotion/react";import{getEnrichmentVectorKey as te}from"@uniformdev/context";import{AddListButton as vt,Button as yt,Callout as ne,Icon as oe,Input as Oe,InputSelect as xt,LoadingIndicator as Dt}from"@uniformdev/design-system";import Ee from"immer";import{useMemo as Ve,useState as ee}from"react";import{CgCloseO as It,CgMathMinus as wt,CgMathPlus as Rt}from"react-icons/cg";import{Fragment as Pe,jsx as u,jsxs as M}from"@emotion/react/jsx-runtime";var Mt=re`
691
+ `;
692
+
693
+ // src/components/EditLink/EditLink.tsx
694
+ import { jsx as jsx14, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
695
+ var EditLink = ({ linkTo, name, linkText = `Edit ${name} Component` }) => {
696
+ return /* @__PURE__ */ jsxs6(
697
+ "a",
698
+ {
699
+ css: editLink,
700
+ title: `Edit ${name} component definition`,
701
+ rel: "noopener noreferrer",
702
+ target: "_blank",
703
+ href: linkTo,
704
+ children: [
705
+ linkText,
706
+ /* @__PURE__ */ jsx14(Icon3, { icon: CgChevronRight, iconColor: "currentColor", size: "1.5rem" })
707
+ ]
708
+ }
709
+ );
710
+ };
711
+
712
+ // src/components/EnrichmentTag/EnrichmentTag.tsx
713
+ import { css as css4 } from "@emotion/react";
714
+ import { getEnrichmentVectorKey } from "@uniformdev/context";
715
+ import {
716
+ AddListButton,
717
+ Button,
718
+ Callout,
719
+ Icon as Icon4,
720
+ Input,
721
+ InputSelect,
722
+ LoadingIndicator as LoadingIndicator2
723
+ } from "@uniformdev/design-system";
724
+ import produce from "immer";
725
+ import { useMemo, useState as useState4 } from "react";
726
+ import { CgCloseO, CgMathMinus, CgMathPlus } from "react-icons/cg";
727
+ import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
728
+ var addEnrichmentLink = css4`
28
729
  flex: 2;
29
730
  display: flex;
30
731
  width: 50%;
@@ -35,7 +736,189 @@ import{jsx as c}from"@emotion/react";import*as h from"react";import{InputComboBo
35
736
  &:focus {
36
737
  text-decoration-line: underline;
37
738
  }
38
- `,or=({value:e,setValue:t,contextConfig:o,displayTitle:a=!0})=>{let{loading:r,result:n,error:s}=V(o),i=Ve(()=>{if(n)return n.dimensions.filter(b=>b.category==="ENR")},[n]),l=Ve(()=>{if(!e)return i;if(i)return i.filter(b=>!e.some(I=>te(I.cat,I.key)===b.dim))},[i,e]),[d,C]=ee(""),[p,m]=ee(50),[f,w]=ee(!1),g=i==null?void 0:i.find(b=>b.dim===d),y=()=>{let[b,I]=d.split("_");R([...e!=null?e:[],{cat:b,key:I,str:p}]),C(""),m(50),w(!1)},R=b=>{let I=[];n?I=b.filter(S=>{let k=n.dimIndex[te(S.cat,S.key)];return Boolean(k)}):I=b;let T=I.length===0?null:I;t(T)};return s?u(ne,{type:"danger",children:s}):r||n===null?u(Dt,{}):M("fieldset",{className:"enrichment-tag",children:[a?u("div",{css:{display:"flex",justifyContent:"space-between",marginBottom:"var(--spacing-base)"},children:u("legend",{css:{fontSize:"var(--fs-md)",fontWeight:"var(--fw-bold)"},children:"Enrichment Tags"})}):null,i!=null&&i.length?!f&&!e?u(ne,{title:"No enrichment tags assigned.",type:"info",css:{marginBlock:"var(--spacing-base)"},children:M("p",{children:["Click"," ",u("a",{onClick:()=>w(!0),target:"_blank",rel:"noopener noreferrer",css:{textDecorationLine:"underline"},children:"here"})," ","to assign your first enrichment tag."]})}):M(Pe,{children:[n&&u(St,{list:e!=null?e:[],setList:R,dimIndex:n.dimIndex}),f&&l&&l.length>0?M("div",{className:"add-enrichment-tag",css:{display:"flex",flexWrap:"wrap",gap:"var(--spacing-lg)",marginTop:"var(--spacing-md)",alignItems:"center"},children:[u("div",{css:{flexGrow:1},children:u(xt,{name:"enrichment-type",label:"Enrichment Tag",showLabel:!0,value:d,options:[{label:"Select",value:""},...l.map(b=>({label:b.displayName,value:b.dim}))],onChange:b=>C(b.currentTarget.value)})}),u(Ot,{score:p,setValue:m,cap:g?g.cap:100,css:{flexBasis:"9rem"}}),u(yt,{buttonType:"tertiary",size:"xl",css:{marginBottom:"var(--spacing-xs)",height:"3.5rem",margin:0,alignSelf:"flex-end"},onClick:y,disabled:!d,children:"Add"})]}):null,M("div",{className:"enrichment-cta",style:{paddingTop:"10px",display:"flex",justifyContent:"space-between"},children:[!f&&l&&l.length>0&&e?u(vt,{className:"add-more",buttonText:"Add More",onButtonClick:()=>w(!0)}):u("a",{css:Mt,title:"none",href:"#"}),u(Me,{name:"Enrichments",linkText:"Manage Enrichments",linkTo:`${o.apiHost}/projects/${encodeURIComponent(o.projectId)}/personalization/enrichments`})]})]}):u(Et,{contextConfig:o})]})},Et=({contextConfig:e})=>u(ne,{title:"No enrichments found.",type:"caution",css:{marginBlock:"var(--spacing-base)"},children:M("p",{children:["Looks like you do not have any enrichment created in your connected Uniform project. Start by creating your first enrichment"," ",u("a",{href:`${e.apiHost}/projects/${encodeURIComponent(e.projectId)}/personalization/enrichments`,target:"_blank",rel:"noopener noreferrer",css:{":hover":{textDecorationLine:"underline"}},children:"here"}),"."]})}),Se=(e,t=100,o=0)=>Math.max(Math.min(e,t),o),Be=re`
739
+ `;
740
+ var EnrichmentTag = ({
741
+ value,
742
+ setValue,
743
+ contextConfig,
744
+ displayTitle = true
745
+ }) => {
746
+ const { loading, result: dimensions, error } = useDimensions(contextConfig);
747
+ const allEnrichments = useMemo(() => {
748
+ if (dimensions)
749
+ return dimensions.dimensions.filter((dimension) => dimension.category === "ENR");
750
+ }, [dimensions]);
751
+ const remainingEnrichments = useMemo(() => {
752
+ if (!value)
753
+ return allEnrichments;
754
+ if (allEnrichments)
755
+ return allEnrichments.filter(
756
+ (enr) => !value.some((val) => getEnrichmentVectorKey(val.cat, val.key) === enr.dim)
757
+ );
758
+ }, [allEnrichments, value]);
759
+ const [selectValue, setSelectValue] = useState4("");
760
+ const [score, setScore] = useState4(50);
761
+ const [showAddNewEnrichmentTagPanel, setShowAddNewEnrichmentTagPanel] = useState4(false);
762
+ const selectedEnrichment = allEnrichments == null ? void 0 : allEnrichments.find((dimension) => dimension.dim === selectValue);
763
+ const addEnrichment = () => {
764
+ const [cat, key] = selectValue.split("_");
765
+ update([...value != null ? value : [], { cat, key, str: score }]);
766
+ setSelectValue("");
767
+ setScore(50);
768
+ setShowAddNewEnrichmentTagPanel(false);
769
+ };
770
+ const update = (newValue) => {
771
+ let validData = [];
772
+ if (dimensions) {
773
+ validData = newValue.filter((enrichment) => {
774
+ const dimData = dimensions.dimIndex[getEnrichmentVectorKey(enrichment.cat, enrichment.key)];
775
+ return Boolean(dimData);
776
+ });
777
+ } else {
778
+ validData = newValue;
779
+ }
780
+ const finalValue = validData.length === 0 ? null : validData;
781
+ setValue(finalValue);
782
+ };
783
+ if (error)
784
+ return /* @__PURE__ */ jsx15(Callout, { type: "danger", children: error });
785
+ if (loading || dimensions === null)
786
+ return /* @__PURE__ */ jsx15(LoadingIndicator2, {});
787
+ return /* @__PURE__ */ jsxs7("fieldset", { className: "enrichment-tag", children: [
788
+ displayTitle ? /* @__PURE__ */ jsx15("div", { css: { display: "flex", justifyContent: "space-between", marginBottom: "var(--spacing-base)" }, children: /* @__PURE__ */ jsx15("legend", { css: { fontSize: "var(--fs-md)", fontWeight: "var(--fw-bold)" }, children: "Enrichment Tags" }) }) : null,
789
+ !(allEnrichments == null ? void 0 : allEnrichments.length) ? /* @__PURE__ */ jsx15(NoEnrichmentsView, { contextConfig }) : !showAddNewEnrichmentTagPanel && !value ? /* @__PURE__ */ jsx15(
790
+ Callout,
791
+ {
792
+ title: "No enrichment tags assigned.",
793
+ type: "info",
794
+ css: { marginBlock: "var(--spacing-base)" },
795
+ children: /* @__PURE__ */ jsxs7("p", { children: [
796
+ "Click",
797
+ " ",
798
+ /* @__PURE__ */ jsx15(
799
+ "a",
800
+ {
801
+ onClick: () => setShowAddNewEnrichmentTagPanel(true),
802
+ target: "_blank",
803
+ rel: "noopener noreferrer",
804
+ css: { textDecorationLine: "underline" },
805
+ children: "here"
806
+ }
807
+ ),
808
+ " ",
809
+ "to assign your first enrichment tag."
810
+ ] })
811
+ }
812
+ ) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
813
+ dimensions && /* @__PURE__ */ jsx15(SelectedEnrichments, { list: value != null ? value : [], setList: update, dimIndex: dimensions.dimIndex }),
814
+ showAddNewEnrichmentTagPanel && remainingEnrichments && remainingEnrichments.length > 0 ? /* @__PURE__ */ jsxs7(
815
+ "div",
816
+ {
817
+ className: "add-enrichment-tag",
818
+ css: {
819
+ display: "flex",
820
+ flexWrap: "wrap",
821
+ gap: "var(--spacing-lg)",
822
+ marginTop: "var(--spacing-md)",
823
+ alignItems: "center"
824
+ },
825
+ children: [
826
+ /* @__PURE__ */ jsx15("div", { css: { flexGrow: 1 }, children: /* @__PURE__ */ jsx15(
827
+ InputSelect,
828
+ {
829
+ name: `enrichment-type`,
830
+ label: "Enrichment Tag",
831
+ showLabel: true,
832
+ value: selectValue,
833
+ options: [
834
+ { label: "Select", value: "" },
835
+ ...remainingEnrichments.map((enr) => ({
836
+ label: enr.displayName,
837
+ value: enr.dim
838
+ }))
839
+ ],
840
+ onChange: (e) => setSelectValue(e.currentTarget.value)
841
+ }
842
+ ) }),
843
+ /* @__PURE__ */ jsx15(
844
+ ScoreCounter,
845
+ {
846
+ score,
847
+ setValue: setScore,
848
+ cap: selectedEnrichment ? selectedEnrichment.cap : 100,
849
+ css: { flexBasis: "9rem" }
850
+ }
851
+ ),
852
+ /* @__PURE__ */ jsx15(
853
+ Button,
854
+ {
855
+ buttonType: "tertiary",
856
+ size: "xl",
857
+ css: {
858
+ marginBottom: "var(--spacing-xs)",
859
+ height: "3.5rem",
860
+ margin: 0,
861
+ alignSelf: "flex-end"
862
+ },
863
+ onClick: addEnrichment,
864
+ disabled: !selectValue,
865
+ children: "Add"
866
+ }
867
+ )
868
+ ]
869
+ }
870
+ ) : null,
871
+ /* @__PURE__ */ jsxs7(
872
+ "div",
873
+ {
874
+ className: "enrichment-cta",
875
+ style: { paddingTop: "10px", display: "flex", justifyContent: "space-between" },
876
+ children: [
877
+ !showAddNewEnrichmentTagPanel && remainingEnrichments && remainingEnrichments.length > 0 && value ? /* @__PURE__ */ jsx15(
878
+ AddListButton,
879
+ {
880
+ className: "add-more",
881
+ buttonText: "Add More",
882
+ onButtonClick: () => setShowAddNewEnrichmentTagPanel(true)
883
+ }
884
+ ) : /* @__PURE__ */ jsx15("a", { css: addEnrichmentLink, title: `none`, href: "#" }),
885
+ /* @__PURE__ */ jsx15(
886
+ EditLink,
887
+ {
888
+ name: "Enrichments",
889
+ linkText: "Manage Enrichments",
890
+ linkTo: `${contextConfig.apiHost}/projects/${encodeURIComponent(
891
+ contextConfig.projectId
892
+ )}/personalization/enrichments`
893
+ }
894
+ )
895
+ ]
896
+ }
897
+ )
898
+ ] })
899
+ ] });
900
+ };
901
+ var NoEnrichmentsView = ({ contextConfig }) => /* @__PURE__ */ jsx15(Callout, { title: "No enrichments found.", type: "caution", css: { marginBlock: "var(--spacing-base)" }, children: /* @__PURE__ */ jsxs7("p", { children: [
902
+ "Looks like you do not have any enrichment created in your connected Uniform project. Start by creating your first enrichment",
903
+ " ",
904
+ /* @__PURE__ */ jsx15(
905
+ "a",
906
+ {
907
+ href: `${contextConfig.apiHost}/projects/${encodeURIComponent(
908
+ contextConfig.projectId
909
+ )}/personalization/enrichments`,
910
+ target: "_blank",
911
+ rel: "noopener noreferrer",
912
+ css: { ":hover": { textDecorationLine: "underline" } },
913
+ children: "here"
914
+ }
915
+ ),
916
+ "."
917
+ ] }) });
918
+ var getCappedValue = (value, maxCap = 100, minCap = 0) => {
919
+ return Math.max(Math.min(value, maxCap), minCap);
920
+ };
921
+ var scoreCounterMinusButtonStyles = css4`
39
922
  position: absolute;
40
923
  bottom: 0.875rem;
41
924
  left: var(--spacing-sm);
@@ -47,28 +930,198 @@ import{jsx as c}from"@emotion/react";import*as h from"react";import{InputComboBo
47
930
  background-color: var(--gray-100);
48
931
  border: 1px solid var(--gray-300);
49
932
  border-radius: var(--rounded-full);
50
- `,Vt=re`
51
- ${Be}
933
+ `;
934
+ var scoreCounterPlusButtonStyles = css4`
935
+ ${scoreCounterMinusButtonStyles}
52
936
  left: auto;
53
937
  right: var(--spacing-sm);
54
- `,Ot=({score:e,setValue:t,cap:o=100,...a})=>{let r=n=>{let s=n==="increment"?e+10:e-10;s<0&&(s=0),s>o&&(s=o),t(s)};return M("div",{css:{position:"relative"},...a,children:[u(Oe,{label:"Strength",id:"enrichment-score",type:"number",min:0,max:o,value:e,onChange:n=>t(Se(Number(n.currentTarget.value)||0,o)),css:{textAlign:"center",boxSizing:"border-box"}}),u("button",{type:"button",title:"Reduce enrichment count",onClick:()=>r("decrement"),disabled:e===0,className:"scoreCounterButton",css:Be,children:u(oe,{icon:wt,iconColor:"gray",size:"1.5rem"})}),u("button",{type:"button",title:"Increase enrichment count",onClick:()=>r("increment"),className:"scoreCounterButton",css:Vt,children:u(oe,{icon:Rt,iconColor:"gray",size:"1.5rem"})})]})},St=({list:e,setList:t,dimIndex:o})=>{let a=n=>{t(Ee(e,s=>{s.splice(n,1)}))},r=(n,s)=>{var l;let i=(l=o[`${e[n].cat}_${e[n].key}`])==null?void 0:l.cap;t(Ee(e,d=>{d[n].str=Se(Number(s)||0,i)}))};return u(Pe,{children:e.map((n,s)=>{let i=o[te(n.cat,n.key)];if(!!i)return M("div",{css:{display:"flex",alignItems:"center",gap:"var(--spacing-base)",backgroundColor:"var(--brand-secondary-2)",boxShadow:"var(--shadow-base)",borderRadius:"var(--rounded-base)",paddingInline:"var(--spacing-base)",marginBlock:"var(--spacing-base)"},className:"selected-enrichments",children:[u("span",{css:{fontWeight:"var(--fw-bold)",color:i?void 0:"var(--brand-secondary-5)"},children:i?i.displayName:`Enrichment '${n.cat}_${n.key}' is unknown`}),u("div",{css:{marginLeft:"auto",display:"flex",alignItems:"center",border:"0 solid var(--gray-400)",borderLeftWidth:"1px",borderRightWidth:"1px",padding:"var(--spacing-sm) var(--spacing-base)",flexBasis:"9rem"},children:u(Oe,{type:"text",min:0,max:i.cap||100,title:"score",value:n.str,css:{textAlign:"center",width:"100px"},onChange:l=>r(s,l.currentTarget.value)})}),u("button",{type:"button",title:"Delete enrichment",onClick:()=>a(s),css:{border:0},children:u(oe,{icon:It,iconColor:"red",size:"1.5rem"})})]},`${n.cat}-${n.key}`)})})};import{Callout as Ae,LoadingIndicator as $t}from"@uniformdev/design-system";import{useState as At}from"react";import{useAsync as Ut}from"react-use";import*as D from"yup";function sr(e){return Array.isArray(e)&&e.length>0&&e[0].cat!==void 0}function lr(e){return e.crit!==void 0}function ie(e){return e!=="+"&&e!=="-"}import{css as Pt}from"@emotion/react";import{AddListButton as Tt,Callout as ze,Icon as kt,InputInlineSelect as Nt,Paragraph as zt}from"@uniformdev/design-system";import Le from"immer";import{CgCloseO as Lt}from"react-icons/cg";import{css as O}from"@emotion/react";var ae="6rem",Te=O`
938
+ `;
939
+ var ScoreCounter = ({
940
+ score,
941
+ setValue,
942
+ cap = 100,
943
+ ...otherProps
944
+ }) => {
945
+ const handleCounter = (symbol) => {
946
+ let newScore = symbol === "increment" ? score + 10 : score - 10;
947
+ if (newScore < 0) {
948
+ newScore = 0;
949
+ }
950
+ if (newScore > cap) {
951
+ newScore = cap;
952
+ }
953
+ setValue(newScore);
954
+ };
955
+ return /* @__PURE__ */ jsxs7("div", { css: { position: "relative" }, ...otherProps, children: [
956
+ /* @__PURE__ */ jsx15(
957
+ Input,
958
+ {
959
+ label: "Strength",
960
+ id: "enrichment-score",
961
+ type: "number",
962
+ min: 0,
963
+ max: cap,
964
+ value: score,
965
+ onChange: (e) => setValue(getCappedValue(Number(e.currentTarget.value) || 0, cap)),
966
+ css: { textAlign: "center", boxSizing: "border-box" }
967
+ }
968
+ ),
969
+ /* @__PURE__ */ jsx15(
970
+ "button",
971
+ {
972
+ type: "button",
973
+ title: "Reduce enrichment count",
974
+ onClick: () => handleCounter("decrement"),
975
+ disabled: score === 0,
976
+ className: "scoreCounterButton",
977
+ css: scoreCounterMinusButtonStyles,
978
+ children: /* @__PURE__ */ jsx15(Icon4, { icon: CgMathMinus, iconColor: "gray", size: "1.5rem" })
979
+ }
980
+ ),
981
+ /* @__PURE__ */ jsx15(
982
+ "button",
983
+ {
984
+ type: "button",
985
+ title: "Increase enrichment count",
986
+ onClick: () => handleCounter("increment"),
987
+ className: "scoreCounterButton",
988
+ css: scoreCounterPlusButtonStyles,
989
+ children: /* @__PURE__ */ jsx15(Icon4, { icon: CgMathPlus, iconColor: "gray", size: "1.5rem" })
990
+ }
991
+ )
992
+ ] });
993
+ };
994
+ var SelectedEnrichments = ({ list, setList, dimIndex }) => {
995
+ const removeEnrichment = (index) => {
996
+ setList(
997
+ produce(list, (draft) => {
998
+ draft.splice(index, 1);
999
+ })
1000
+ );
1001
+ };
1002
+ const updateEnrichmentScore = (index, value) => {
1003
+ var _a;
1004
+ const cap = (_a = dimIndex[`${list[index].cat}_${list[index].key}`]) == null ? void 0 : _a.cap;
1005
+ setList(
1006
+ produce(list, (draft) => {
1007
+ draft[index].str = getCappedValue(Number(value) || 0, cap);
1008
+ })
1009
+ );
1010
+ };
1011
+ return /* @__PURE__ */ jsx15(Fragment4, { children: list.map((enrichment, index) => {
1012
+ const dimData = dimIndex[getEnrichmentVectorKey(enrichment.cat, enrichment.key)];
1013
+ if (!dimData)
1014
+ return;
1015
+ return /* @__PURE__ */ jsxs7(
1016
+ "div",
1017
+ {
1018
+ css: {
1019
+ display: "flex",
1020
+ alignItems: "center",
1021
+ gap: "var(--spacing-base)",
1022
+ backgroundColor: "var(--brand-secondary-2)",
1023
+ boxShadow: "var(--shadow-base)",
1024
+ borderRadius: "var(--rounded-base)",
1025
+ paddingInline: "var(--spacing-base)",
1026
+ marginBlock: "var(--spacing-base)"
1027
+ },
1028
+ className: "selected-enrichments",
1029
+ children: [
1030
+ /* @__PURE__ */ jsx15(
1031
+ "span",
1032
+ {
1033
+ css: { fontWeight: "var(--fw-bold)", color: dimData ? void 0 : "var(--brand-secondary-5)" },
1034
+ children: dimData ? dimData.displayName : `Enrichment '${enrichment.cat}_${enrichment.key}' is unknown`
1035
+ }
1036
+ ),
1037
+ /* @__PURE__ */ jsx15(
1038
+ "div",
1039
+ {
1040
+ css: {
1041
+ marginLeft: "auto",
1042
+ display: "flex",
1043
+ alignItems: "center",
1044
+ border: "0 solid var(--gray-400)",
1045
+ borderLeftWidth: "1px",
1046
+ borderRightWidth: "1px",
1047
+ padding: "var(--spacing-sm) var(--spacing-base)",
1048
+ flexBasis: "9rem"
1049
+ },
1050
+ children: /* @__PURE__ */ jsx15(
1051
+ Input,
1052
+ {
1053
+ type: "text",
1054
+ min: 0,
1055
+ max: dimData.cap || 100,
1056
+ title: "score",
1057
+ value: enrichment.str,
1058
+ css: { textAlign: "center", width: "100px" },
1059
+ onChange: (e) => updateEnrichmentScore(index, e.currentTarget.value)
1060
+ }
1061
+ )
1062
+ }
1063
+ ),
1064
+ /* @__PURE__ */ jsx15(
1065
+ "button",
1066
+ {
1067
+ type: "button",
1068
+ title: `Delete enrichment`,
1069
+ onClick: () => removeEnrichment(index),
1070
+ css: { border: 0 },
1071
+ children: /* @__PURE__ */ jsx15(Icon4, { icon: CgCloseO, iconColor: "red", size: "1.5rem" })
1072
+ }
1073
+ )
1074
+ ]
1075
+ },
1076
+ `${enrichment.cat}-${enrichment.key}`
1077
+ );
1078
+ }) });
1079
+ };
1080
+
1081
+ // src/components/PersonalizationCriteria/PersonalizationCriteria.tsx
1082
+ import { Callout as Callout3, LoadingIndicator as LoadingIndicator3 } from "@uniformdev/design-system";
1083
+ import { useState as useState5 } from "react";
1084
+ import { useAsync } from "react-use";
1085
+ import * as yup from "yup";
1086
+
1087
+ // src/utils/utils.ts
1088
+ function isEnrichmentTagData(obj) {
1089
+ return Array.isArray(obj) && obj.length > 0 && obj[0].cat !== void 0;
1090
+ }
1091
+ function isPersonalizationCriteriaData(obj) {
1092
+ return obj.crit !== void 0;
1093
+ }
1094
+ function opHasRhs(op) {
1095
+ return op !== "+" && op !== "-";
1096
+ }
1097
+
1098
+ // src/components/PersonalizationCriteria/PersonalizationCriteriaStatic.tsx
1099
+ import { css as css6 } from "@emotion/react";
1100
+ import { AddListButton as AddListButton2, Callout as Callout2, Icon as Icon5, InputInlineSelect, Paragraph } from "@uniformdev/design-system";
1101
+ import produce2 from "immer";
1102
+ import { CgCloseO as CgCloseO2 } from "react-icons/cg";
1103
+
1104
+ // src/components/PersonalizationCriteria/PersonalizationCriteriaStatic.styles.ts
1105
+ import { css as css5 } from "@emotion/react";
1106
+ var spaceBetweenCriteriaItems = "6rem";
1107
+ var criteriaItem = css5`
55
1108
  position: relative;
56
1109
  padding: var(--spacing-md) var(--spacing-base);
57
1110
  border: 1px solid var(--gray-300);
58
1111
  box-shadow: var(--shadow-base);
59
1112
  background-color: white;
60
1113
  border-radius: var(--rounded-base);
61
- margin-top: ${ae};
1114
+ margin-top: ${spaceBetweenCriteriaItems};
62
1115
  display: flex;
63
1116
 
64
1117
  &:before {
65
1118
  content: '';
66
1119
  display: block;
67
1120
  width: 1px;
68
- height: ${ae};
1121
+ height: ${spaceBetweenCriteriaItems};
69
1122
  background-color: var(--gray-300);
70
1123
  position: absolute;
71
- top: -${ae};
1124
+ top: -${spaceBetweenCriteriaItems};
72
1125
  left: var(--spacing-lg);
73
1126
  }
74
1127
 
@@ -78,27 +1131,448 @@ import{jsx as c}from"@emotion/react";import*as h from"react";import{InputComboBo
78
1131
  display: none;
79
1132
  }
80
1133
  }
81
- `,ke=O`
1134
+ `;
1135
+ var criteriaItemInner = css5`
82
1136
  display: flex;
83
1137
  gap: var(--spacing-base);
84
1138
  flex-grow: 1;
85
1139
  flex-wrap: wrap;
86
1140
  margin-right: var(--spacing-base);
87
- `,F=O`
1141
+ `;
1142
+ var criteriaWrapper = css5`
88
1143
  width: 100%;
89
1144
  display: flex;
90
1145
  align-items: stretch;
91
1146
  position: relative;
92
- `,se=O`
1147
+ `;
1148
+ var criteriaOperandWrapper = css5`
93
1149
  flex: 2;
94
1150
  height: 52px;
95
1151
  min-width: 200px;
96
- `,Ne=O`
1152
+ `;
1153
+ var criteriaOperatorWrapper = css5`
97
1154
  flex: 1;
98
1155
  min-width: 80px;
99
- `,j=O`
1156
+ `;
1157
+ var expand = css5`
100
1158
  height: 100%;
101
1159
  width: 100%;
102
- `;import{jsx as v,jsxs as le}from"@emotion/react/jsx-runtime";var $e=({value:e,setValue:t,dimensions:o,onMenuOpen:a,onMenuClose:r,onAddCriteria:n,onRemoveCriteria:s,displayTitle:i=!0,components:l,errors:d={}})=>{let C=e||{crit:[]},p=g=>{t({...C,op:g==="&"?void 0:g})},m=()=>{let g={...C,crit:[...C.crit,{l:"",op:">",r:0}]};t(g),n==null||n(g)},f=(g,y)=>{t(Le(C,R=>{R.crit[y]=g}))},w=g=>{let y=Le(C,b=>{b.crit.splice(g,1)}),R=y.crit.length===0?null:y;t(R),s==null||s(R)};return le("fieldset",{className:"personalization-criteria",children:[i?l!=null&&l.Title?v(l.Title,{}):v("legend",{css:{fontSize:"var(--fs-md)",fontWeight:"var(--fw-bold)"},children:"Personalize This"}):null,l!=null&&l.CustomVariantName?v(l.CustomVariantName,{}):null,C.crit.length?v("div",{children:C.crit.map((g,y)=>{var I,T,S,k;let R=((I=g.l)==null?void 0:I.length)>0,b=g.op!=="+"&&g.op!=="-";return le("div",{css:Te,"data-test-id":"criteria-container",children:[le("div",{css:Pt`
103
- ${ke}/* grid-template-columns: minmax(0, 1fr) ${b?"minmax(0, 79px) minmax(0, 1fr)":"minmax(0, 1fr)"} */
104
- `,className:"criteriaItemInner",children:[v("div",{css:[F,se],className:"criteria-wrapper","data-test-id":"select-criteria",children:v(we,{errorMessage:(T=d.lhs)==null?void 0:T[y],css:j,styles:{control:x=>({...x,height:"100%"})},dimensions:o.dimensions,onChange:x=>{f({...g,l:x.dim},y)},value:o.dimIndex[g.l],onMenuOpen:a,onMenuClose:r})}),v("div",{css:[F,Ne],className:"criteria-wrapper","data-test-id":"select-operator",children:v(ge,{name:`op-${y}`,css:j,styles:{control:x=>({...x,height:"100%"})},value:g.op,onChange:x=>{f(x==="+"||x==="-"?{...g,op:x,r:void 0,rDim:void 0}:{...g,op:x},y)},onMenuOpen:a,onMenuClose:r})}),b?v("div",{css:[F,se],className:"criteria-wrapper","data-test-id":"select-match-criteria",children:v(De,{errorMessage:(S=d.rhs)==null?void 0:S[y],css:j,styles:{control:x=>({...x,height:"100%"})},criteriaMatch:g,onChange:x=>{f(x,y)},isDisabled:!R,dimensions:o,onMenuOpen:a,onMenuClose:r})}):null]}),v("button",{type:"button",onClick:()=>w(y),title:"Delete Personalization",css:{backgroundColor:"transparent",backgroundImage:"none",borderWidth:0},"data-test-id":"button-delete",children:v(kt,{icon:Lt,iconColor:"red",size:"1.5rem"})}),y>0?v("div",{className:"criteria-group-operation",css:{position:"absolute",top:"-4rem",transform:"translateX(calc(1.5rem - 50%))"},children:v(Nt,{"data-test-id":"dropdown-button-combine",disabled:y>1,value:(k=C.op)!=null?k:"&",options:[{label:"AND",value:"&"},{label:"OR",value:"|"}],onChange:x=>{p(x.value)}})}):null]},y)})}):v(ze,{title:"Default variant",type:"info",css:{marginBlock:"var(--spacing-base)"},children:v(zt,{children:'This personalized variant has no match criteria and will be shown to any visitor that does not match any preceding variants. Ensure that default variants come last in the variant list. Personalize this variant by clicking "Add Criteria" to get started.'})}),o.dimensions.length===0?l!=null&&l.NoDimensionsDefined?v(l.NoDimensionsDefined,{}):v(ze,{title:"Dimensions",type:"info",css:{marginBlock:"var(--spacing-base)"},children:v("p",{children:"You do not have any dimensions configured."})}):v(Tt,{"data-test-id":"button-add-criteria",className:"add-more",buttonText:"Add Criteria",onButtonClick:m})]})};import{jsx as P,jsxs as Ht}from"@emotion/react/jsx-runtime";function Gt(e){let t={crit:[]};return e.forEach(o=>{if(!o.path)return;let a=/\[(\d+)\]\.(\w+)/g,r=[...o.path.matchAll(a)][0];if((r==null?void 0:r.length)==3){let n=Number(r[1]),s=r[2];if(t.crit.length>n)t.crit[n]={...t.crit[n],[s]:o.message};else{let i={};i[s]=o.message,t.crit.push(i)}}}),t}async function me(e,t){let o=D.object().shape({l:D.string().required("Please select a dimension").oneOf(t==null?void 0:t.dimensions.map(a=>a.dim),"Select a criteria"),op:D.string().required(),r:D.mixed().nullable().when(["rDim","op"],{is:(a,r)=>ie(r)&&!a,then:D.string().required("Choose a score or dimension")}),rDim:D.string().oneOf(t==null?void 0:t.dimensions.map(a=>a.dim),"Select a criteria").when(["r","op"],{is:(a,r)=>ie(r)&&!a,then:D.string().required("Choose a score or dimension")})},["rDim","r"]);try{await D.object({crit:D.array(o)}).nullable().validate(e,{abortEarly:!1})}catch(a){return Gt(a.inner)}}var Sr=({contextConfig:e,value:t,setValue:o,...a})=>{var C,p;let[r,n]=At(void 0),{loading:s,result:i,error:l}=V(e);return Ut(async()=>{if(t&&i){let m=await me(t,i);n(m)}},[t,i,me]),l?P(Ae,{type:"danger",children:l}):s||i===null?P($t,{}):P($e,{...a,value:t,setValue:async m=>{let f=await me(m,i);n(f),o(m)},errors:{lhs:(C=r==null?void 0:r.crit)==null?void 0:C.map(m=>m==null?void 0:m.l),rhs:(p=r==null?void 0:r.crit)==null?void 0:p.map(m=>m==null?void 0:m.rDim)},dimensions:i,components:{NoDimensionsDefined:()=>P(Ae,{title:"Dimensions",type:"info",css:{marginBlock:"var(--spacing-base)"},children:Ht("p",{children:["You do not have any dimensions configured. Create your first"," ",P("a",{href:`${e.apiHost}/projects/${encodeURIComponent(e.projectId)}/personalization/signals`,target:"_blank",rel:"noopener noreferrer",css:{":hover":{textDecorationLine:"underline"}},children:"Dimension"})]})})}})};import{LoadingIndicator as Wt}from"@uniformdev/design-system";import{Fragment as qt,jsx as pe}from"@emotion/react/jsx-runtime";function zr({children:e,versionMap:t,contextConfig:o}){let{loading:a,result:r}=z(o);if(a)return pe(Wt,{});if(r){let n=t[r.project.ui_version];if(n)return pe(n,{})}return pe(qt,{children:e})}import{useEffect as jt,useState as Kt}from"react";import{UncachedManifestClient as _t}from"@uniformdev/context/api";import{validate as Ft}from"uuid";var Ue=async e=>{if(!e)return{valid:!1,error:new Error("contextConfig was not defined.")};if(!e.apiHost)return{valid:!1,error:new Error("apiHost was not defined.")};if(!e.apiKey)return{valid:!1,error:new Error("apiKey was not defined.")};if(!Ft(e.apiKey)&&!e.projectId)return{valid:!1,error:new Error("projectId is required when using a modern API key.")};let t=new _t({projectId:e.projectId,apiKey:e.apiKey,apiHost:e.apiHost});try{return{valid:!0,result:await t.get({preview:!0})}}catch(o){return{valid:!1,error:o}}};var jr=e=>{let[t,o]=Kt({validating:!1,error:void 0}),{apiKey:a,apiHost:r,projectId:n}=e||{};return jt(()=>{if(!a||!r)return;(async()=>{o({validating:!0,error:void 0});let{error:i,result:l}=await Ue({apiHost:r,apiKey:a,projectId:n});o(i?{error:i,validating:!1}:{error:void 0,validating:!1,result:l})})()},[r,a,n]),{validating:t.validating,error:t.error,result:t.result}};export*from"@uniformdev/design-system";export{$n as ContextData,De as CriteriaMatchMenu,ge as CriteriaOperatorMenu,we as DimensionMenu,ye as DimensionValue,Me as EditLink,or as EnrichmentTag,Sr as PersonalizationCriteria,$e as PersonalizationCriteriaStatic,zr as ProjectUIVersion,Mt as addEnrichmentLink,fe as contextCriteriaMenuOperators,Gt as convertErrorsToObj,sr as isEnrichmentTagData,lr as isPersonalizationCriteriaData,ie as opHasRhs,An as useContextConfig,z as useContextData,V as useDimensions,Gn as useDimensionsDataContext,Un as useManifest,jr as useValidateContextConfig,Ue as validateContextConfig};
1160
+ `;
1161
+
1162
+ // src/components/PersonalizationCriteria/PersonalizationCriteriaStatic.tsx
1163
+ import { jsx as jsx16, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
1164
+ var PersonalizationCriteriaStatic = ({
1165
+ value,
1166
+ setValue,
1167
+ dimensions,
1168
+ onMenuOpen,
1169
+ onMenuClose,
1170
+ onAddCriteria,
1171
+ onRemoveCriteria,
1172
+ displayTitle = true,
1173
+ components,
1174
+ errors = {}
1175
+ }) => {
1176
+ const currentValue = value || {
1177
+ crit: []
1178
+ };
1179
+ const setOp = (op) => {
1180
+ const finalOp = op === "&" ? void 0 : op;
1181
+ setValue({
1182
+ ...currentValue,
1183
+ op: finalOp
1184
+ });
1185
+ };
1186
+ const addToList = () => {
1187
+ const newValue = {
1188
+ ...currentValue,
1189
+ crit: [...currentValue.crit, { l: "", op: ">", r: 0 }]
1190
+ };
1191
+ setValue(newValue);
1192
+ onAddCriteria == null ? void 0 : onAddCriteria(newValue);
1193
+ };
1194
+ const update = (crit, index) => {
1195
+ setValue(
1196
+ produce2(currentValue, (draft) => {
1197
+ draft.crit[index] = crit;
1198
+ })
1199
+ );
1200
+ };
1201
+ const removeFromList = (index) => {
1202
+ const newValue = produce2(currentValue, (draft) => {
1203
+ draft.crit.splice(index, 1);
1204
+ });
1205
+ const finalValue = newValue.crit.length === 0 ? null : newValue;
1206
+ setValue(finalValue);
1207
+ onRemoveCriteria == null ? void 0 : onRemoveCriteria(finalValue);
1208
+ };
1209
+ return /* @__PURE__ */ jsxs8("fieldset", { className: "personalization-criteria", children: [
1210
+ displayTitle ? (components == null ? void 0 : components.Title) ? /* @__PURE__ */ jsx16(components.Title, {}) : /* @__PURE__ */ jsx16(
1211
+ "legend",
1212
+ {
1213
+ css: {
1214
+ fontSize: "var(--fs-md)",
1215
+ fontWeight: "var(--fw-bold)"
1216
+ },
1217
+ children: "Personalize This"
1218
+ }
1219
+ ) : null,
1220
+ (components == null ? void 0 : components.CustomVariantName) ? /* @__PURE__ */ jsx16(components.CustomVariantName, {}) : null,
1221
+ !currentValue.crit.length ? /* @__PURE__ */ jsx16(Callout2, { title: "Default variant", type: "info", css: { marginBlock: "var(--spacing-base)" }, children: /* @__PURE__ */ jsx16(Paragraph, { children: 'This personalized variant has no match criteria and will be shown to any visitor that does not match any preceding variants. Ensure that default variants come last in the variant list. Personalize this variant by clicking "Add Criteria" to get started.' }) }) : /* @__PURE__ */ jsx16("div", { children: currentValue.crit.map((currentCriteria, index) => {
1222
+ var _a, _b, _c, _d;
1223
+ const critHasLhs = ((_a = currentCriteria.l) == null ? void 0 : _a.length) > 0;
1224
+ const critHasRhs = currentCriteria.op !== "+" && currentCriteria.op !== "-";
1225
+ return /* @__PURE__ */ jsxs8("div", { css: criteriaItem, "data-test-id": "criteria-container", children: [
1226
+ /* @__PURE__ */ jsxs8(
1227
+ "div",
1228
+ {
1229
+ css: css6`
1230
+ ${criteriaItemInner}/* grid-template-columns: minmax(0, 1fr) ${critHasRhs ? "minmax(0, 79px) minmax(0, 1fr)" : "minmax(0, 1fr)"} */
1231
+ `,
1232
+ className: "criteriaItemInner",
1233
+ children: [
1234
+ /* @__PURE__ */ jsx16(
1235
+ "div",
1236
+ {
1237
+ css: [criteriaWrapper, criteriaOperandWrapper],
1238
+ className: "criteria-wrapper",
1239
+ "data-test-id": "select-criteria",
1240
+ children: /* @__PURE__ */ jsx16(
1241
+ DimensionMenu,
1242
+ {
1243
+ errorMessage: (_b = errors.lhs) == null ? void 0 : _b[index],
1244
+ css: expand,
1245
+ styles: { control: (base) => ({ ...base, height: "100%" }) },
1246
+ dimensions: dimensions.dimensions,
1247
+ onChange: (dim) => {
1248
+ update({ ...currentCriteria, l: dim.dim }, index);
1249
+ },
1250
+ value: dimensions.dimIndex[currentCriteria.l],
1251
+ onMenuOpen,
1252
+ onMenuClose
1253
+ }
1254
+ )
1255
+ }
1256
+ ),
1257
+ /* @__PURE__ */ jsx16(
1258
+ "div",
1259
+ {
1260
+ css: [criteriaWrapper, criteriaOperatorWrapper],
1261
+ className: "criteria-wrapper",
1262
+ "data-test-id": "select-operator",
1263
+ children: /* @__PURE__ */ jsx16(
1264
+ CriteriaOperatorMenu,
1265
+ {
1266
+ name: `op-${index}`,
1267
+ css: expand,
1268
+ styles: { control: (base) => ({ ...base, height: "100%" }) },
1269
+ value: currentCriteria.op,
1270
+ onChange: (op) => {
1271
+ if (op === "+" || op === "-") {
1272
+ update({ ...currentCriteria, op, r: void 0, rDim: void 0 }, index);
1273
+ } else {
1274
+ update({ ...currentCriteria, op }, index);
1275
+ }
1276
+ },
1277
+ onMenuOpen,
1278
+ onMenuClose
1279
+ }
1280
+ )
1281
+ }
1282
+ ),
1283
+ critHasRhs ? /* @__PURE__ */ jsx16(
1284
+ "div",
1285
+ {
1286
+ css: [criteriaWrapper, criteriaOperandWrapper],
1287
+ className: "criteria-wrapper",
1288
+ "data-test-id": "select-match-criteria",
1289
+ children: /* @__PURE__ */ jsx16(
1290
+ CriteriaMatchMenu,
1291
+ {
1292
+ errorMessage: (_c = errors.rhs) == null ? void 0 : _c[index],
1293
+ css: expand,
1294
+ styles: { control: (base) => ({ ...base, height: "100%" }) },
1295
+ criteriaMatch: currentCriteria,
1296
+ onChange: (match) => {
1297
+ update(match, index);
1298
+ },
1299
+ isDisabled: !critHasLhs,
1300
+ dimensions,
1301
+ onMenuOpen,
1302
+ onMenuClose
1303
+ }
1304
+ )
1305
+ }
1306
+ ) : null
1307
+ ]
1308
+ }
1309
+ ),
1310
+ /* @__PURE__ */ jsx16(
1311
+ "button",
1312
+ {
1313
+ type: "button",
1314
+ onClick: () => removeFromList(index),
1315
+ title: `Delete Personalization`,
1316
+ css: { backgroundColor: "transparent", backgroundImage: "none", borderWidth: 0 },
1317
+ "data-test-id": "button-delete",
1318
+ children: /* @__PURE__ */ jsx16(Icon5, { icon: CgCloseO2, iconColor: "red", size: "1.5rem" })
1319
+ }
1320
+ ),
1321
+ index > 0 ? /* @__PURE__ */ jsx16(
1322
+ "div",
1323
+ {
1324
+ className: "criteria-group-operation",
1325
+ css: {
1326
+ position: "absolute",
1327
+ top: "-4rem",
1328
+ transform: "translateX(calc(1.5rem - 50%))"
1329
+ },
1330
+ children: /* @__PURE__ */ jsx16(
1331
+ InputInlineSelect,
1332
+ {
1333
+ "data-test-id": "dropdown-button-combine",
1334
+ disabled: index > 1,
1335
+ value: (_d = currentValue.op) != null ? _d : "&",
1336
+ options: [
1337
+ { label: "AND", value: "&" },
1338
+ { label: "OR", value: "|" }
1339
+ ],
1340
+ onChange: (v) => {
1341
+ setOp(v.value);
1342
+ }
1343
+ }
1344
+ )
1345
+ }
1346
+ ) : null
1347
+ ] }, index);
1348
+ }) }),
1349
+ dimensions.dimensions.length === 0 ? (components == null ? void 0 : components.NoDimensionsDefined) ? /* @__PURE__ */ jsx16(components.NoDimensionsDefined, {}) : /* @__PURE__ */ jsx16(Callout2, { title: "Dimensions", type: "info", css: { marginBlock: "var(--spacing-base)" }, children: /* @__PURE__ */ jsx16("p", { children: "You do not have any dimensions configured." }) }) : /* @__PURE__ */ jsx16(
1350
+ AddListButton2,
1351
+ {
1352
+ "data-test-id": "button-add-criteria",
1353
+ className: "add-more",
1354
+ buttonText: "Add Criteria",
1355
+ onButtonClick: addToList
1356
+ }
1357
+ )
1358
+ ] });
1359
+ };
1360
+
1361
+ // src/components/PersonalizationCriteria/PersonalizationCriteria.tsx
1362
+ import { jsx as jsx17, jsxs as jsxs9 } from "@emotion/react/jsx-runtime";
1363
+ function convertErrorsToObj(errors) {
1364
+ const result = { crit: [] };
1365
+ errors.forEach((err) => {
1366
+ var _a;
1367
+ if (!err.path)
1368
+ return;
1369
+ const regexp = /\[(\d+)\]\.(\w+)/g;
1370
+ const matches = (_a = [...err.path.matchAll(regexp)]) == null ? void 0 : _a[0];
1371
+ if ((matches == null ? void 0 : matches.length) == 3) {
1372
+ const index = Number(matches[1]);
1373
+ const prop = matches[2];
1374
+ if (result.crit.length > index) {
1375
+ result.crit[index] = { ...result.crit[index], [prop]: err.message };
1376
+ } else {
1377
+ const variant = {};
1378
+ variant[prop] = err.message;
1379
+ result.crit.push(variant);
1380
+ }
1381
+ }
1382
+ });
1383
+ return result;
1384
+ }
1385
+ async function validate(value, contextData) {
1386
+ const schema = yup.object().shape(
1387
+ {
1388
+ l: yup.string().required("Please select a dimension").oneOf(
1389
+ contextData == null ? void 0 : contextData.dimensions.map((d) => d.dim),
1390
+ "Select a criteria"
1391
+ ),
1392
+ op: yup.string().required(),
1393
+ r: yup.mixed().nullable().when(["rDim", "op"], {
1394
+ is: (rDim, op) => opHasRhs(op) && !rDim,
1395
+ then: yup.string().required("Choose a score or dimension")
1396
+ }),
1397
+ rDim: yup.string().oneOf(
1398
+ contextData == null ? void 0 : contextData.dimensions.map((d) => d.dim),
1399
+ "Select a criteria"
1400
+ ).when(["r", "op"], {
1401
+ is: (r, op) => opHasRhs(op) && !r,
1402
+ then: yup.string().required("Choose a score or dimension")
1403
+ })
1404
+ },
1405
+ ["rDim", "r"]
1406
+ );
1407
+ try {
1408
+ await yup.object({
1409
+ crit: yup.array(schema)
1410
+ }).nullable().validate(value, { abortEarly: false });
1411
+ } catch (e) {
1412
+ return convertErrorsToObj(e.inner);
1413
+ }
1414
+ }
1415
+ var PersonalizationCriteria = ({
1416
+ contextConfig,
1417
+ value,
1418
+ setValue,
1419
+ ...staticProps
1420
+ }) => {
1421
+ var _a, _b;
1422
+ const [validationError, setValidationError] = useState5(void 0);
1423
+ const { loading, result: dimensions, error } = useDimensions(contextConfig);
1424
+ useAsync(async () => {
1425
+ if (value && dimensions) {
1426
+ const err = await validate(value, dimensions);
1427
+ setValidationError(err);
1428
+ }
1429
+ }, [value, dimensions, validate]);
1430
+ if (error)
1431
+ return /* @__PURE__ */ jsx17(Callout3, { type: "danger", children: error });
1432
+ if (loading || dimensions === null)
1433
+ return /* @__PURE__ */ jsx17(LoadingIndicator3, {});
1434
+ const handleSetValue = async (value2) => {
1435
+ const err = await validate(value2, dimensions);
1436
+ setValidationError(err);
1437
+ setValue(value2);
1438
+ };
1439
+ return /* @__PURE__ */ jsx17(
1440
+ PersonalizationCriteriaStatic,
1441
+ {
1442
+ ...staticProps,
1443
+ value,
1444
+ setValue: handleSetValue,
1445
+ errors: {
1446
+ lhs: (_a = validationError == null ? void 0 : validationError.crit) == null ? void 0 : _a.map((err) => err == null ? void 0 : err.l),
1447
+ rhs: (_b = validationError == null ? void 0 : validationError.crit) == null ? void 0 : _b.map((err) => err == null ? void 0 : err.rDim)
1448
+ },
1449
+ dimensions,
1450
+ components: {
1451
+ NoDimensionsDefined: () => /* @__PURE__ */ jsx17(Callout3, { title: "Dimensions", type: "info", css: { marginBlock: "var(--spacing-base)" }, children: /* @__PURE__ */ jsxs9("p", { children: [
1452
+ "You do not have any dimensions configured. Create your first",
1453
+ " ",
1454
+ /* @__PURE__ */ jsx17(
1455
+ "a",
1456
+ {
1457
+ href: `${contextConfig.apiHost}/projects/${encodeURIComponent(
1458
+ contextConfig.projectId
1459
+ )}/personalization/signals`,
1460
+ target: "_blank",
1461
+ rel: "noopener noreferrer",
1462
+ css: { ":hover": { textDecorationLine: "underline" } },
1463
+ children: "Dimension"
1464
+ }
1465
+ )
1466
+ ] }) })
1467
+ }
1468
+ }
1469
+ );
1470
+ };
1471
+
1472
+ // src/components/ProjectUIVersion/ProjectUIVersion.tsx
1473
+ import { LoadingIndicator as LoadingIndicator4 } from "@uniformdev/design-system";
1474
+ import { Fragment as Fragment5, jsx as jsx18 } from "@emotion/react/jsx-runtime";
1475
+ function ProjectUIVersion({ children, versionMap, contextConfig }) {
1476
+ const { loading, result: data } = useContextData(contextConfig);
1477
+ if (loading)
1478
+ return /* @__PURE__ */ jsx18(LoadingIndicator4, {});
1479
+ if (data) {
1480
+ const Component = versionMap[data.project.ui_version];
1481
+ if (Component) {
1482
+ return /* @__PURE__ */ jsx18(Component, {});
1483
+ }
1484
+ }
1485
+ return /* @__PURE__ */ jsx18(Fragment5, { children });
1486
+ }
1487
+
1488
+ // src/hooks/useValidateContextConfig.ts
1489
+ import { useEffect as useEffect3, useState as useState6 } from "react";
1490
+
1491
+ // src/utils/validateContextConfig.ts
1492
+ import { UncachedManifestClient } from "@uniformdev/context/api";
1493
+ import { validate as validate2 } from "uuid";
1494
+ var validateContextConfig = async (contextConfig) => {
1495
+ if (!contextConfig) {
1496
+ return { valid: false, error: new Error("contextConfig was not defined.") };
1497
+ }
1498
+ if (!contextConfig.apiHost) {
1499
+ return { valid: false, error: new Error("apiHost was not defined.") };
1500
+ }
1501
+ if (!contextConfig.apiKey) {
1502
+ return { valid: false, error: new Error("apiKey was not defined.") };
1503
+ }
1504
+ if (!validate2(contextConfig.apiKey) && !contextConfig.projectId) {
1505
+ return { valid: false, error: new Error("projectId is required when using a modern API key.") };
1506
+ }
1507
+ const client = new UncachedManifestClient({
1508
+ projectId: contextConfig.projectId,
1509
+ apiKey: contextConfig.apiKey,
1510
+ apiHost: contextConfig.apiHost
1511
+ });
1512
+ try {
1513
+ const result = await client.get({ preview: true });
1514
+ return {
1515
+ valid: true,
1516
+ result
1517
+ };
1518
+ } catch (e) {
1519
+ return { valid: false, error: e };
1520
+ }
1521
+ };
1522
+
1523
+ // src/hooks/useValidateContextConfig.ts
1524
+ var useValidateContextConfig = (contextConfig) => {
1525
+ const [state, setState] = useState6({
1526
+ validating: false,
1527
+ error: void 0
1528
+ });
1529
+ const { apiKey, apiHost, projectId } = contextConfig || {};
1530
+ useEffect3(() => {
1531
+ if (!apiKey || !apiHost) {
1532
+ return;
1533
+ }
1534
+ const runEffect = async () => {
1535
+ setState({ validating: true, error: void 0 });
1536
+ const { error, result } = await validateContextConfig({ apiHost, apiKey, projectId });
1537
+ if (error) {
1538
+ setState({ error, validating: false });
1539
+ } else {
1540
+ setState({ error: void 0, validating: false, result });
1541
+ }
1542
+ };
1543
+ runEffect();
1544
+ }, [apiHost, apiKey, projectId]);
1545
+ return {
1546
+ validating: state.validating,
1547
+ error: state.error,
1548
+ result: state.result
1549
+ };
1550
+ };
1551
+
1552
+ // src/index.ts
1553
+ export * from "@uniformdev/design-system";
1554
+ export {
1555
+ ContextData,
1556
+ CriteriaMatchMenu,
1557
+ CriteriaOperatorMenu,
1558
+ DimensionMenu,
1559
+ DimensionValue,
1560
+ EditLink,
1561
+ EnrichmentTag,
1562
+ PersonalizationCriteria,
1563
+ PersonalizationCriteriaStatic,
1564
+ ProjectUIVersion,
1565
+ addEnrichmentLink,
1566
+ contextCriteriaMenuOperators,
1567
+ convertErrorsToObj,
1568
+ isEnrichmentTagData,
1569
+ isPersonalizationCriteriaData,
1570
+ opHasRhs,
1571
+ useContextConfig,
1572
+ useContextData,
1573
+ useDimensions,
1574
+ useDimensionsDataContext,
1575
+ useManifest,
1576
+ useValidateContextConfig,
1577
+ validateContextConfig
1578
+ };