@contractspec/lib.example-shared-ui 6.0.5 → 6.0.7
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/.turbo/turbo-build.log +90 -84
- package/AGENTS.md +43 -25
- package/CHANGELOG.md +11 -0
- package/README.md +63 -35
- package/dist/EvolutionDashboard.js +9 -9
- package/dist/EvolutionSidebar.js +15 -15
- package/dist/LocalDataIndicator.js +3 -3
- package/dist/MarkdownView.d.ts +0 -7
- package/dist/MarkdownView.js +76 -172
- package/dist/PersonalizationInsights.js +12 -12
- package/dist/SaveToStudioButton.js +2 -2
- package/dist/SpecDrivenTemplateShell.d.ts +1 -1
- package/dist/SpecDrivenTemplateShell.js +10 -10
- package/dist/SpecEditorPanel.js +3 -3
- package/dist/TemplateShell.js +10 -10
- package/dist/browser/EvolutionDashboard.js +9 -9
- package/dist/browser/EvolutionSidebar.js +15 -15
- package/dist/browser/LocalDataIndicator.js +3 -3
- package/dist/browser/MarkdownView.js +76 -172
- package/dist/browser/PersonalizationInsights.js +12 -12
- package/dist/browser/SaveToStudioButton.js +2 -2
- package/dist/browser/SpecDrivenTemplateShell.js +10 -10
- package/dist/browser/SpecEditorPanel.js +3 -3
- package/dist/browser/TemplateShell.js +10 -10
- package/dist/browser/hooks/index.js +29 -29
- package/dist/browser/index.js +193 -286
- package/dist/browser/lib/component-registry.js +1 -1
- package/dist/browser/markdown/formatPresentationName.js +9 -0
- package/dist/browser/markdown/useMarkdownPresentation.js +65 -0
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/index.js +29 -29
- package/dist/index.d.ts +12 -11
- package/dist/index.js +193 -286
- package/dist/lib/component-registry.js +1 -1
- package/dist/markdown/formatPresentationName.d.ts +1 -0
- package/dist/markdown/formatPresentationName.js +10 -0
- package/dist/markdown/useMarkdownPresentation.d.ts +21 -0
- package/dist/markdown/useMarkdownPresentation.js +66 -0
- package/dist/node/EvolutionDashboard.js +9 -9
- package/dist/node/EvolutionSidebar.js +15 -15
- package/dist/node/LocalDataIndicator.js +3 -3
- package/dist/node/MarkdownView.js +76 -172
- package/dist/node/PersonalizationInsights.js +12 -12
- package/dist/node/SaveToStudioButton.js +2 -2
- package/dist/node/SpecDrivenTemplateShell.js +10 -10
- package/dist/node/SpecEditorPanel.js +3 -3
- package/dist/node/TemplateShell.js +10 -10
- package/dist/node/hooks/index.js +29 -29
- package/dist/node/index.js +193 -286
- package/dist/node/lib/component-registry.js +1 -1
- package/dist/node/markdown/formatPresentationName.js +9 -0
- package/dist/node/markdown/useMarkdownPresentation.js +65 -0
- package/dist/utils/index.d.ts +1 -1
- package/package.json +40 -13
- package/src/EvolutionDashboard.tsx +415 -415
- package/src/EvolutionSidebar.tsx +245 -245
- package/src/LocalDataIndicator.tsx +28 -28
- package/src/MarkdownView.tsx +119 -372
- package/src/OverlayContextProvider.tsx +272 -272
- package/src/PersonalizationInsights.tsx +232 -232
- package/src/SaveToStudioButton.tsx +51 -51
- package/src/SpecDrivenTemplateShell.tsx +59 -59
- package/src/SpecEditorPanel.tsx +138 -138
- package/src/TemplateShell.tsx +50 -50
- package/src/bundles/ExampleTemplateBundle.ts +78 -78
- package/src/hooks/index.ts +3 -3
- package/src/hooks/useBehaviorTracking.ts +252 -252
- package/src/hooks/useEvolution.ts +437 -437
- package/src/hooks/useRegistryTemplates.ts +42 -42
- package/src/hooks/useSpecContent.ts +214 -214
- package/src/hooks/useWorkflowComposer.ts +567 -567
- package/src/index.ts +12 -11
- package/src/lib/component-registry.tsx +40 -40
- package/src/lib/runtime-context.tsx +31 -31
- package/src/lib/types.ts +57 -57
- package/src/markdown/formatPresentationName.ts +9 -0
- package/src/markdown/useMarkdownPresentation.ts +107 -0
- package/src/overlay-types.ts +15 -15
- package/src/utils/fetchPresentationData.ts +13 -13
- package/src/utils/generateSpecFromTemplate.ts +29 -29
- package/src/utils/index.ts +1 -1
- package/tsconfig.json +8 -8
|
@@ -8,59 +8,59 @@ import type { TemplateId } from './lib/types';
|
|
|
8
8
|
* Overlay modification operation types (for OverlayContextProvider)
|
|
9
9
|
*/
|
|
10
10
|
export type OverlayModificationOp =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
| { op: 'hide' }
|
|
12
|
+
| { op: 'relabel'; label: string }
|
|
13
|
+
| { op: 'reorder'; position: number }
|
|
14
|
+
| { op: 'restyle'; className?: string; variant?: string }
|
|
15
|
+
| { op: 'set-default'; value: unknown };
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Overlay spec for a field or component
|
|
19
19
|
*/
|
|
20
20
|
export interface OverlaySpec {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
id: string;
|
|
22
|
+
target: string; // path to the field/component
|
|
23
|
+
modifications: OverlayModificationOp[];
|
|
24
|
+
conditions?: {
|
|
25
|
+
role?: string[];
|
|
26
|
+
device?: 'mobile' | 'desktop' | 'any';
|
|
27
|
+
featureFlags?: string[];
|
|
28
|
+
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Context value for overlay engine
|
|
33
33
|
*/
|
|
34
34
|
export interface OverlayContextValue {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
/** Current overlays */
|
|
36
|
+
overlays: OverlaySpec[];
|
|
37
|
+
/** Apply overlays to a component */
|
|
38
|
+
applyOverlay: <T extends Record<string, unknown>>(
|
|
39
|
+
path: string,
|
|
40
|
+
target: T
|
|
41
|
+
) => T;
|
|
42
|
+
/** Check if a field should be hidden */
|
|
43
|
+
isHidden: (path: string) => boolean;
|
|
44
|
+
/** Get relabeled text */
|
|
45
|
+
getLabel: (path: string, defaultLabel: string) => string;
|
|
46
|
+
/** Get position for reordering */
|
|
47
|
+
getPosition: (path: string, defaultPosition: number) => number;
|
|
48
|
+
/** Get style modifications */
|
|
49
|
+
getStyle: (path: string) => { className?: string; variant?: string };
|
|
50
|
+
/** Get default value */
|
|
51
|
+
getDefault: <T>(path: string, defaultValue: T) => T;
|
|
52
|
+
/** Current user role */
|
|
53
|
+
role: string;
|
|
54
|
+
/** Current device type */
|
|
55
|
+
device: 'mobile' | 'desktop';
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const OverlayContext = React.createContext<OverlayContextValue | null>(null);
|
|
59
59
|
|
|
60
60
|
export interface OverlayContextProviderProps extends React.PropsWithChildren {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
templateId: TemplateId;
|
|
62
|
+
role?: string;
|
|
63
|
+
device?: 'mobile' | 'desktop';
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/**
|
|
@@ -68,274 +68,274 @@ export interface OverlayContextProviderProps extends React.PropsWithChildren {
|
|
|
68
68
|
* Loads template-specific overlays and provides helper functions.
|
|
69
69
|
*/
|
|
70
70
|
export function OverlayContextProvider({
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
templateId,
|
|
72
|
+
role = 'user',
|
|
73
|
+
device = 'desktop',
|
|
74
|
+
children,
|
|
75
75
|
}: OverlayContextProviderProps) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
// Load template-specific overlays
|
|
77
|
+
const overlays = useMemo(
|
|
78
|
+
() => getTemplateOverlays(templateId, role),
|
|
79
|
+
[templateId, role]
|
|
80
|
+
);
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
// Filter overlays based on current context
|
|
83
|
+
const activeOverlays = useMemo(() => {
|
|
84
|
+
return overlays.filter((overlay) => {
|
|
85
|
+
const conditions = overlay.conditions;
|
|
86
|
+
if (!conditions) return true;
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
if (conditions.role && !conditions.role.includes(role)) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
92
|
+
if (
|
|
93
|
+
conditions.device &&
|
|
94
|
+
conditions.device !== 'any' &&
|
|
95
|
+
conditions.device !== device
|
|
96
|
+
) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
}, [overlays, role, device]);
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
// Create overlay map for quick lookups
|
|
105
|
+
const overlayMap = useMemo(() => {
|
|
106
|
+
const map = new Map<string, OverlaySpec>();
|
|
107
|
+
for (const overlay of activeOverlays) {
|
|
108
|
+
map.set(overlay.target, overlay);
|
|
109
|
+
}
|
|
110
|
+
return map;
|
|
111
|
+
}, [activeOverlays]);
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
// Apply overlay to a target object
|
|
114
|
+
const applyOverlay = useMemo(
|
|
115
|
+
() =>
|
|
116
|
+
<T extends Record<string, unknown>>(path: string, target: T): T => {
|
|
117
|
+
const overlay = overlayMap.get(path);
|
|
118
|
+
if (!overlay) return target;
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
120
|
+
let result = { ...target };
|
|
121
|
+
for (const mod of overlay.modifications) {
|
|
122
|
+
switch (mod.op) {
|
|
123
|
+
case 'hide':
|
|
124
|
+
result = { ...result, hidden: true };
|
|
125
|
+
break;
|
|
126
|
+
case 'relabel':
|
|
127
|
+
result = { ...result, label: mod.label };
|
|
128
|
+
break;
|
|
129
|
+
case 'reorder':
|
|
130
|
+
result = { ...result, position: mod.position };
|
|
131
|
+
break;
|
|
132
|
+
case 'restyle':
|
|
133
|
+
result = {
|
|
134
|
+
...result,
|
|
135
|
+
className: mod.className,
|
|
136
|
+
variant: mod.variant,
|
|
137
|
+
};
|
|
138
|
+
break;
|
|
139
|
+
case 'set-default':
|
|
140
|
+
result = { ...result, defaultValue: mod.value };
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
},
|
|
146
|
+
[overlayMap]
|
|
147
|
+
);
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
149
|
+
// Check if field is hidden
|
|
150
|
+
const isHidden = useMemo(
|
|
151
|
+
() =>
|
|
152
|
+
(path: string): boolean => {
|
|
153
|
+
const overlay = overlayMap.get(path);
|
|
154
|
+
return overlay?.modifications.some((m) => m.op === 'hide') ?? false;
|
|
155
|
+
},
|
|
156
|
+
[overlayMap]
|
|
157
|
+
);
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
// Get relabeled text
|
|
160
|
+
const getLabel = useMemo(
|
|
161
|
+
() =>
|
|
162
|
+
(path: string, defaultLabel: string): string => {
|
|
163
|
+
const overlay = overlayMap.get(path);
|
|
164
|
+
const relabel = overlay?.modifications.find((m) => m.op === 'relabel');
|
|
165
|
+
return relabel && relabel.op === 'relabel'
|
|
166
|
+
? relabel.label
|
|
167
|
+
: defaultLabel;
|
|
168
|
+
},
|
|
169
|
+
[overlayMap]
|
|
170
|
+
);
|
|
171
171
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
172
|
+
// Get position for reordering
|
|
173
|
+
const getPosition = useMemo(
|
|
174
|
+
() =>
|
|
175
|
+
(path: string, defaultPosition: number): number => {
|
|
176
|
+
const overlay = overlayMap.get(path);
|
|
177
|
+
const reorder = overlay?.modifications.find((m) => m.op === 'reorder');
|
|
178
|
+
return reorder && reorder.op === 'reorder'
|
|
179
|
+
? reorder.position
|
|
180
|
+
: defaultPosition;
|
|
181
|
+
},
|
|
182
|
+
[overlayMap]
|
|
183
|
+
);
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
185
|
+
// Get style modifications
|
|
186
|
+
const getStyle = useMemo(
|
|
187
|
+
() =>
|
|
188
|
+
(path: string): { className?: string; variant?: string } => {
|
|
189
|
+
const overlay = overlayMap.get(path);
|
|
190
|
+
const restyle = overlay?.modifications.find((m) => m.op === 'restyle');
|
|
191
|
+
if (restyle && restyle.op === 'restyle') {
|
|
192
|
+
return {
|
|
193
|
+
className: restyle.className,
|
|
194
|
+
variant: restyle.variant,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return {};
|
|
198
|
+
},
|
|
199
|
+
[overlayMap]
|
|
200
|
+
);
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
202
|
+
// Get default value
|
|
203
|
+
const getDefault = useMemo(
|
|
204
|
+
() =>
|
|
205
|
+
<T,>(path: string, defaultValue: T): T => {
|
|
206
|
+
const overlay = overlayMap.get(path);
|
|
207
|
+
const setDefault = overlay?.modifications.find(
|
|
208
|
+
(m) => m.op === 'set-default'
|
|
209
|
+
);
|
|
210
|
+
return setDefault && setDefault.op === 'set-default'
|
|
211
|
+
? (setDefault.value as T)
|
|
212
|
+
: defaultValue;
|
|
213
|
+
},
|
|
214
|
+
[overlayMap]
|
|
215
|
+
);
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
217
|
+
const value = useMemo<OverlayContextValue>(
|
|
218
|
+
() => ({
|
|
219
|
+
overlays: activeOverlays,
|
|
220
|
+
applyOverlay,
|
|
221
|
+
isHidden,
|
|
222
|
+
getLabel,
|
|
223
|
+
getPosition,
|
|
224
|
+
getStyle,
|
|
225
|
+
getDefault,
|
|
226
|
+
role,
|
|
227
|
+
device,
|
|
228
|
+
}),
|
|
229
|
+
[
|
|
230
|
+
activeOverlays,
|
|
231
|
+
applyOverlay,
|
|
232
|
+
isHidden,
|
|
233
|
+
getLabel,
|
|
234
|
+
getPosition,
|
|
235
|
+
getStyle,
|
|
236
|
+
getDefault,
|
|
237
|
+
role,
|
|
238
|
+
device,
|
|
239
|
+
]
|
|
240
|
+
);
|
|
241
241
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
242
|
+
return (
|
|
243
|
+
<OverlayContext.Provider value={value}>{children}</OverlayContext.Provider>
|
|
244
|
+
);
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
/**
|
|
248
248
|
* Hook to access overlay context
|
|
249
249
|
*/
|
|
250
250
|
export function useOverlayContext(): OverlayContextValue {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
251
|
+
const context = useContext(OverlayContext);
|
|
252
|
+
if (!context) {
|
|
253
|
+
throw new Error(
|
|
254
|
+
'useOverlayContext must be used within an OverlayContextProvider'
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return context;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
/**
|
|
261
261
|
* Hook to check if within overlay context
|
|
262
262
|
*/
|
|
263
263
|
export function useIsInOverlayContext(): boolean {
|
|
264
|
-
|
|
264
|
+
return useContext(OverlayContext) !== null;
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
/**
|
|
268
268
|
* Get template-specific overlays
|
|
269
269
|
*/
|
|
270
270
|
function getTemplateOverlays(
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
templateId: TemplateId,
|
|
272
|
+
_role: string
|
|
273
273
|
): OverlaySpec[] {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
274
|
+
// Demo overlays for each template
|
|
275
|
+
const templateOverlays: Record<string, OverlaySpec[]> = {
|
|
276
|
+
'crm-pipeline': [
|
|
277
|
+
{
|
|
278
|
+
id: 'crm-hide-internal-fields',
|
|
279
|
+
target: 'deal.internalNotes',
|
|
280
|
+
modifications: [{ op: 'hide' }],
|
|
281
|
+
conditions: { role: ['viewer', 'user'] },
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
id: 'crm-relabel-value',
|
|
285
|
+
target: 'deal.value',
|
|
286
|
+
modifications: [{ op: 'relabel', label: 'Deal Amount' }],
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
'saas-boilerplate': [
|
|
290
|
+
{
|
|
291
|
+
id: 'saas-hide-billing',
|
|
292
|
+
target: 'settings.billing',
|
|
293
|
+
modifications: [{ op: 'hide' }],
|
|
294
|
+
conditions: { role: ['viewer'] },
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 'saas-restyle-plan',
|
|
298
|
+
target: 'settings.plan',
|
|
299
|
+
modifications: [{ op: 'restyle', variant: 'premium' }],
|
|
300
|
+
conditions: { role: ['admin'] },
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
'agent-console': [
|
|
304
|
+
{
|
|
305
|
+
id: 'agent-hide-cost',
|
|
306
|
+
target: 'run.cost',
|
|
307
|
+
modifications: [{ op: 'hide' }],
|
|
308
|
+
conditions: { role: ['viewer'] },
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
id: 'agent-relabel-tokens',
|
|
312
|
+
target: 'run.tokens',
|
|
313
|
+
modifications: [{ op: 'relabel', label: 'Token Usage' }],
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
'todos-app': [
|
|
317
|
+
{
|
|
318
|
+
id: 'todos-hide-assignee',
|
|
319
|
+
target: 'task.assignee',
|
|
320
|
+
modifications: [{ op: 'hide' }],
|
|
321
|
+
conditions: { device: 'mobile' },
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
'messaging-app': [
|
|
325
|
+
{
|
|
326
|
+
id: 'messaging-reorder-timestamp',
|
|
327
|
+
target: 'message.timestamp',
|
|
328
|
+
modifications: [{ op: 'reorder', position: 0 }],
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
'recipe-app-i18n': [
|
|
332
|
+
{
|
|
333
|
+
id: 'recipe-relabel-servings',
|
|
334
|
+
target: 'recipe.servings',
|
|
335
|
+
modifications: [{ op: 'relabel', label: 'Portions' }],
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
};
|
|
339
339
|
|
|
340
|
-
|
|
340
|
+
return templateOverlays[templateId] ?? [];
|
|
341
341
|
}
|