Skip to content

Commit 2a93a47

Browse files
committed
Fix PR comments
Feature: CMS-47083
1 parent 1080571 commit 2a93a47

File tree

4 files changed

+83
-52
lines changed

4 files changed

+83
-52
lines changed

packages/optimizely-cms-sdk/src/infer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,12 @@ type InferFromDisplayTemplate<T extends DisplayTemplate> =
190190
T extends { settings: infer S }
191191
? {
192192
[K in keyof S]:
193-
S[K] extends { choices: Record<string, any> }
194-
? keyof S[K]['choices']
193+
S[K] extends { choices: Record<string, any>; editor: infer E }
194+
? E extends 'select'
195+
? keyof S[K]['choices']
196+
: E extends 'checkbox'
197+
? 'true' | 'false'
198+
: never
195199
: never;
196200
}
197201
: {};
Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,54 @@
11
import { describe, it, expect } from 'vitest';
22
import { parseDisplaySettings } from '../displayTemplates.js';
33

4+
45
describe('parseDisplaySettings', () => {
56
it('should parse valid display settings correctly', () => {
7+
const template = {
8+
settings: {
9+
layout: { editor: 'select', choices: { grid: {}, list: {} } },
10+
theme: { editor: 'select', choices: { dark: {}, light: {} } }
11+
}
12+
} as any;
13+
614
const input = [
715
{ key: 'layout', value: 'grid' },
8-
{ key: 'theme', value: 'dark' },
16+
{ key: 'theme', value: 'dark' }
917
];
10-
const result = parseDisplaySettings(input);
18+
19+
const result = parseDisplaySettings(input, template);
1120
expect(result).toEqual({
1221
layout: 'grid',
13-
theme: 'dark',
22+
theme: 'dark'
1423
});
1524
});
1625

17-
it('should handle missing properties gracefully', () => {
18-
const input = [{ key: 'layout', value: 'grid' }];
19-
const result = parseDisplaySettings(input);
26+
it('should handle checkbox correctly', () => {
27+
const template = {
28+
settings: {
29+
showImage: { editor: 'checkbox', choices: {} }
30+
}
31+
} as any;
32+
33+
const input = [{ key: 'showImage', value: 'true' }];
34+
const result = parseDisplaySettings(input, template);
2035
expect(result).toEqual({
21-
layout: 'grid',
36+
showImage: 'true'
2237
});
2338
});
2439

25-
it('should return an empty object for null input', () => {
40+
it('should return undefined for null input', () => {
41+
const template = { settings: {} } as any;
2642
const input = null;
27-
const result = parseDisplaySettings(input ?? undefined);
28-
expect(result).toEqual({});
43+
const result = parseDisplaySettings(input, template);
44+
expect(result).toBeUndefined();
2945
});
3046

31-
it('should return an empty object for undefined input', () => {
47+
it('should return undefined for undefined input', () => {
48+
const template = { settings: {} } as any;
3249
const input = undefined;
33-
const result = parseDisplaySettings(input);
34-
expect(result).toEqual({});
50+
const result = parseDisplaySettings(input, template);
51+
expect(result).toBeUndefined();
3552
});
3653
});
54+

packages/optimizely-cms-sdk/src/model/displayTemplates.ts

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,30 +62,26 @@ export type DisplayTemplate<T = DisplayTemplateVariant> = T & {
6262
__type: 'displayTemplate';
6363
};
6464

65-
// export function parseDisplaySettings(
66-
// displaySettings?: DisplaySettingsType[] | null
67-
// ): Record<string, string> | undefined {
68-
// if (!displaySettings) {
69-
// return undefined; // Return undefined if displaySettings is not provided
70-
// }
71-
72-
// const result: Record<string, string> = {}; // Initialize an empty object
73-
74-
// // Iterate over the input array
75-
// for (const item of displaySettings) {
76-
// // Assign the value to the key in the result object
77-
// result[item.key] = item.value;
78-
// }
79-
80-
// return result;
81-
// }
82-
83-
export const parseDisplaySettings = <T extends DisplayTemplate>(
84-
settings: DisplaySettingsType[] | null | undefined
85-
): Infer<DisplayTemplate> => {
86-
const result = {} as Infer<T>;
87-
settings?.forEach(s => {
88-
result[s.key as keyof Infer<T>] = s.value as Infer<T>[keyof Infer<T>];
65+
66+
export function parseDisplaySettings(
67+
settings: DisplaySettingsType[] | null | undefined,
68+
templateSettings: Record<string, { editor: string; choices: Record<string, any> }>
69+
): Record<string, string> {
70+
if (!settings || settings.length === 0) return {};
71+
72+
const result: Record<string, string> = {};
73+
74+
settings.forEach(s => {
75+
const settingDef = templateSettings[s.key];
76+
if (!settingDef) return;
77+
78+
if (settingDef.editor === 'select') {
79+
result[s.key] = s.value;
80+
} else if (settingDef.editor === 'checkbox') {
81+
result[s.key] = s.value === 'true' ? 'true' : 'false';
82+
}
8983
});
84+
9085
return result;
91-
};
86+
}
87+

packages/optimizely-cms-sdk/src/react/server.tsx

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import {
1010
ExperienceComponentNode,
1111
DisplaySettingsType,
1212
ExperienceCompositionNode,
13+
Infer,
1314
} from '../infer.js';
1415
import { isComponentNode } from '../util/baseTypeUtil.js';
15-
import { parseDisplaySettings } from '../model/displayTemplates.js';
16-
import { getDisplayTemplateTag } from '../model/displayTemplateRegistry.js';
16+
import { DisplayTemplate, parseDisplaySettings } from '../model/displayTemplates.js';
17+
import { getDisplayTemplate, getDisplayTemplateTag } from '../model/displayTemplateRegistry.js';
1718
import { isDev } from '../util/environment.js';
1819

1920
type ComponentType = React.ComponentType<any>;
@@ -70,7 +71,7 @@ export function initReactComponentRegistry(options: InitOptions) {
7071
}
7172

7273
/** Props for the {@linkcode OptimizelyComponent} component */
73-
type OptimizelyComponentProps = {
74+
type OptimizelyComponentProps<T extends DisplayTemplate = DisplayTemplate> = {
7475
/** Data read from the CMS */
7576
opti: {
7677
/** Content type name */
@@ -87,7 +88,7 @@ type OptimizelyComponentProps = {
8788
__composition?: ExperienceCompositionNode;
8889
};
8990

90-
displaySettings?: Record<string, string>;
91+
displaySettings?: Partial<Infer<T>>;
9192
};
9293

9394
export async function OptimizelyComponent({
@@ -106,8 +107,7 @@ export async function OptimizelyComponent({
106107

107108
if (!Component) {
108109
console.log(
109-
`[optimizely-cms-sdk] No component found for content type ${
110-
opti.__typename
110+
`[optimizely-cms-sdk] No component found for content type ${opti.__typename
111111
} ${opti.__tag ? `with tag "${opti.__tag}"` : ''}`
112112
);
113113

@@ -127,16 +127,16 @@ export async function OptimizelyComponent({
127127
);
128128
}
129129

130-
export type StructureContainerProps = {
130+
export type StructureContainerProps<T extends DisplayTemplate = DisplayTemplate> = {
131131
node: ExperienceStructureNode;
132132
children: React.ReactNode;
133133
index?: number;
134-
displaySettings?: Record<string, string>;
134+
displaySettings?: Partial<Infer<T>>;
135135
};
136-
export type ComponentContainerProps = {
136+
export type ComponentContainerProps<T extends DisplayTemplate = DisplayTemplate> = {
137137
node: ExperienceComponentNode;
138138
children: React.ReactNode;
139-
displaySettings?: Record<string, string>;
139+
displaySettings?: Partial<Infer<T>>;
140140
};
141141
export type StructureContainer = (
142142
props: StructureContainerProps
@@ -154,7 +154,14 @@ export function OptimizelyExperience({
154154
}) {
155155
return nodes.map((node) => {
156156
const tag = getDisplayTemplateTag(node.displayTemplateKey);
157-
const parsedDisplaySettings = parseDisplaySettings(node.displaySettings);
157+
const template = node.displayTemplateKey
158+
? getDisplayTemplate(node.displayTemplateKey)
159+
: null;
160+
161+
const parsedDisplaySettings = template
162+
? parseDisplaySettings(node.displaySettings, template.settings)
163+
: {};
164+
console.error(parsedDisplaySettings);
158165

159166
if (isComponentNode(node)) {
160167
const Wrapper = ComponentWrapper ?? React.Fragment;
@@ -255,7 +262,13 @@ export function OptimizelyGridSection({
255262

256263
return nodes.map((node, i) => {
257264
const tag = getDisplayTemplateTag(node.displayTemplateKey);
258-
const parsedDisplaySettings = parseDisplaySettings(node.displaySettings);
265+
const template = node.displayTemplateKey
266+
? getDisplayTemplate(node.displayTemplateKey)
267+
: null;
268+
269+
const parsedDisplaySettings = template
270+
? parseDisplaySettings(node.displaySettings, template.settings)
271+
: {};
259272

260273
if (isComponentNode(node)) {
261274
return (

0 commit comments

Comments
 (0)