@vertesia/fusion-ux 1.0.0-dev.20260128.144200
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/LICENSE +13 -0
- package/README.md +160 -0
- package/lib/esm/fusion-fragment/ChartRenderer.js +70 -0
- package/lib/esm/fusion-fragment/ChartRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/FieldRenderer.js +153 -0
- package/lib/esm/fusion-fragment/FieldRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/FusionFragmentContext.js +53 -0
- package/lib/esm/fusion-fragment/FusionFragmentContext.js.map +1 -0
- package/lib/esm/fusion-fragment/FusionFragmentHandler.js +233 -0
- package/lib/esm/fusion-fragment/FusionFragmentHandler.js.map +1 -0
- package/lib/esm/fusion-fragment/FusionFragmentRenderer.js +108 -0
- package/lib/esm/fusion-fragment/FusionFragmentRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/SectionRenderer.js +134 -0
- package/lib/esm/fusion-fragment/SectionRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/TableRenderer.js +137 -0
- package/lib/esm/fusion-fragment/TableRenderer.js.map +1 -0
- package/lib/esm/fusion-fragment/index.js +11 -0
- package/lib/esm/fusion-fragment/index.js.map +1 -0
- package/lib/esm/index.js +44 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/render/index.js +12 -0
- package/lib/esm/render/index.js.map +1 -0
- package/lib/esm/render/textPreview.js +194 -0
- package/lib/esm/render/textPreview.js.map +1 -0
- package/lib/esm/types.js +8 -0
- package/lib/esm/types.js.map +1 -0
- package/lib/esm/validation/formatErrors.js +105 -0
- package/lib/esm/validation/formatErrors.js.map +1 -0
- package/lib/esm/validation/fuzzyMatch.js +87 -0
- package/lib/esm/validation/fuzzyMatch.js.map +1 -0
- package/lib/esm/validation/index.js +8 -0
- package/lib/esm/validation/index.js.map +1 -0
- package/lib/esm/validation/schemas.js +166 -0
- package/lib/esm/validation/schemas.js.map +1 -0
- package/lib/esm/validation/validateTemplate.js +247 -0
- package/lib/esm/validation/validateTemplate.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/fusion-fragment/ChartRenderer.d.ts +23 -0
- package/lib/types/fusion-fragment/ChartRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FieldRenderer.d.ts +12 -0
- package/lib/types/fusion-fragment/FieldRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FusionFragmentContext.d.ts +48 -0
- package/lib/types/fusion-fragment/FusionFragmentContext.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FusionFragmentHandler.d.ts +38 -0
- package/lib/types/fusion-fragment/FusionFragmentHandler.d.ts.map +1 -0
- package/lib/types/fusion-fragment/FusionFragmentRenderer.d.ts +32 -0
- package/lib/types/fusion-fragment/FusionFragmentRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/SectionRenderer.d.ts +12 -0
- package/lib/types/fusion-fragment/SectionRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/TableRenderer.d.ts +15 -0
- package/lib/types/fusion-fragment/TableRenderer.d.ts.map +1 -0
- package/lib/types/fusion-fragment/index.d.ts +11 -0
- package/lib/types/fusion-fragment/index.d.ts.map +1 -0
- package/lib/types/index.d.ts +42 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/render/index.d.ts +12 -0
- package/lib/types/render/index.d.ts.map +1 -0
- package/lib/types/render/textPreview.d.ts +20 -0
- package/lib/types/render/textPreview.d.ts.map +1 -0
- package/lib/types/types.d.ts +262 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/validation/formatErrors.d.ts +35 -0
- package/lib/types/validation/formatErrors.d.ts.map +1 -0
- package/lib/types/validation/fuzzyMatch.d.ts +25 -0
- package/lib/types/validation/fuzzyMatch.d.ts.map +1 -0
- package/lib/types/validation/index.d.ts +8 -0
- package/lib/types/validation/index.d.ts.map +1 -0
- package/lib/types/validation/schemas.d.ts +67 -0
- package/lib/types/validation/schemas.d.ts.map +1 -0
- package/lib/types/validation/validateTemplate.d.ts +22 -0
- package/lib/types/validation/validateTemplate.d.ts.map +1 -0
- package/lib/vertesia-fusion-ux.js +2 -0
- package/lib/vertesia-fusion-ux.js.map +1 -0
- package/package.json +68 -0
- package/src/fusion-fragment/ChartRenderer.tsx +136 -0
- package/src/fusion-fragment/FieldRenderer.tsx +199 -0
- package/src/fusion-fragment/FusionFragmentContext.tsx +92 -0
- package/src/fusion-fragment/FusionFragmentHandler.tsx +313 -0
- package/src/fusion-fragment/FusionFragmentRenderer.tsx +156 -0
- package/src/fusion-fragment/SectionRenderer.tsx +196 -0
- package/src/fusion-fragment/TableRenderer.tsx +204 -0
- package/src/fusion-fragment/index.ts +20 -0
- package/src/index.ts +89 -0
- package/src/render/index.ts +16 -0
- package/src/render/textPreview.ts +231 -0
- package/src/types.ts +278 -0
- package/src/validation/formatErrors.ts +128 -0
- package/src/validation/fuzzyMatch.ts +109 -0
- package/src/validation/index.ts +8 -0
- package/src/validation/schemas.ts +175 -0
- package/src/validation/validateTemplate.ts +282 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2024 Composable
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# @vertesia/fusion-ux
|
|
2
|
+
|
|
3
|
+
Dynamic model-generated UI components for Vertesia. Models generate templates (structure), the system provides values (data).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @vertesia/fusion-ux
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Client-side (React)
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import {
|
|
17
|
+
FusionFragmentRenderer,
|
|
18
|
+
FusionFragmentProvider,
|
|
19
|
+
FusionFragmentHandler,
|
|
20
|
+
} from '@vertesia/fusion-ux';
|
|
21
|
+
|
|
22
|
+
// Option 1: Direct rendering with template and data
|
|
23
|
+
<FusionFragmentRenderer
|
|
24
|
+
template={{
|
|
25
|
+
title: "Fund Parameters",
|
|
26
|
+
sections: [{
|
|
27
|
+
title: "Identity",
|
|
28
|
+
layout: "grid-3",
|
|
29
|
+
fields: [
|
|
30
|
+
{ label: "Firm Name", key: "firmName" },
|
|
31
|
+
{ label: "Vintage", key: "vintageYear", format: "number" }
|
|
32
|
+
]
|
|
33
|
+
}]
|
|
34
|
+
}}
|
|
35
|
+
data={{ firmName: "Acme Capital", vintageYear: 2024 }}
|
|
36
|
+
onUpdate={async (key, value) => {
|
|
37
|
+
// Handle field updates
|
|
38
|
+
}}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
// Option 2: Context-based rendering (for markdown code blocks)
|
|
42
|
+
<FusionFragmentProvider data={fund.parameters} onUpdate={handleUpdate}>
|
|
43
|
+
<MarkdownRenderer content={agentResponse} />
|
|
44
|
+
</FusionFragmentProvider>
|
|
45
|
+
|
|
46
|
+
// Option 3: Code block handler for markdown renderers
|
|
47
|
+
const codeBlockRenderers = {
|
|
48
|
+
'fusion-fragment': ({ code }) => <FusionFragmentHandler code={code} />
|
|
49
|
+
};
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Server-side (Tools)
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { fusionUxTools } from '@vertesia/fusion-ux/server';
|
|
56
|
+
|
|
57
|
+
// Register tools with your server
|
|
58
|
+
server.registerCollection(fusionUxTools);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Template Structure
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
interface FragmentTemplate {
|
|
65
|
+
title?: string;
|
|
66
|
+
entityType?: 'fund' | 'scenario' | 'portfolio' | 'transaction' | 'custom';
|
|
67
|
+
sections: SectionTemplate[];
|
|
68
|
+
footer?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface SectionTemplate {
|
|
72
|
+
title: string;
|
|
73
|
+
layout?: 'grid-2' | 'grid-3' | 'grid-4' | 'list';
|
|
74
|
+
collapsed?: boolean;
|
|
75
|
+
fields: FieldTemplate[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface FieldTemplate {
|
|
79
|
+
label: string; // Display label
|
|
80
|
+
key: string; // Data key (required)
|
|
81
|
+
format?: 'text' | 'number' | 'currency' | 'percent' | 'date' | 'boolean';
|
|
82
|
+
unit?: string; // e.g., "years", "USD"
|
|
83
|
+
editable?: boolean;
|
|
84
|
+
highlight?: 'success' | 'warning' | 'error' | 'info';
|
|
85
|
+
tooltip?: string;
|
|
86
|
+
decimals?: number; // For number/currency/percent
|
|
87
|
+
currency?: string; // For currency format
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Validation Tool
|
|
92
|
+
|
|
93
|
+
The `validate_fusion_fragment` tool allows models to validate templates:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"template": {
|
|
98
|
+
"sections": [{
|
|
99
|
+
"title": "Identity",
|
|
100
|
+
"fields": [{ "label": "Firm", "key": "firmName" }]
|
|
101
|
+
}]
|
|
102
|
+
},
|
|
103
|
+
"dataKeys": ["firmName", "fundName", "vintageYear"],
|
|
104
|
+
"preview": "text"
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Returns errors with suggestions or a text preview of the template.
|
|
109
|
+
|
|
110
|
+
## API
|
|
111
|
+
|
|
112
|
+
### Components
|
|
113
|
+
|
|
114
|
+
- `FusionFragmentRenderer` - Main renderer component
|
|
115
|
+
- `FusionFragmentProvider` - Context provider for data
|
|
116
|
+
- `FusionFragmentHandler` - Code block handler
|
|
117
|
+
- `SectionRenderer` - Section renderer
|
|
118
|
+
- `FieldRenderer` - Field renderer
|
|
119
|
+
|
|
120
|
+
### Validation
|
|
121
|
+
|
|
122
|
+
- `validateTemplate(template, dataKeys)` - Validate a template
|
|
123
|
+
- `parseAndValidateTemplate(jsonString, dataKeys)` - Parse and validate
|
|
124
|
+
- `findClosestKey(input, validKeys)` - Fuzzy key matching
|
|
125
|
+
- `formatValidationErrors(errors)` - Format errors for models
|
|
126
|
+
|
|
127
|
+
### Server
|
|
128
|
+
|
|
129
|
+
- `fusionUxTools` - Tool collection for registration
|
|
130
|
+
- `ValidateFusionFragmentTool` - The validation tool
|
|
131
|
+
|
|
132
|
+
### Serverless Rendering
|
|
133
|
+
|
|
134
|
+
Render templates to PNG without a browser using `@napi-rs/canvas`:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { renderToBuffer, renderToBase64, renderToDataUrl } from '@vertesia/fusion-ux/server';
|
|
138
|
+
|
|
139
|
+
// Render to PNG buffer
|
|
140
|
+
const buffer = renderToBuffer(template, data);
|
|
141
|
+
fs.writeFileSync('preview.png', buffer);
|
|
142
|
+
|
|
143
|
+
// Render to base64 string
|
|
144
|
+
const base64 = renderToBase64(template, data);
|
|
145
|
+
|
|
146
|
+
// Render to data URL
|
|
147
|
+
const dataUrl = renderToDataUrl(template, data);
|
|
148
|
+
// Returns: "data:image/png;base64,..."
|
|
149
|
+
|
|
150
|
+
// With custom options
|
|
151
|
+
const buffer = renderToBuffer(template, data, {
|
|
152
|
+
width: 800, // Canvas width (default: 600)
|
|
153
|
+
padding: 24, // Padding around content (default: 20)
|
|
154
|
+
fieldHeight: 60, // Height per field row (default: 50)
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
Apache-2.0
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFusionFragmentContextSafe } from './FusionFragmentContext.js';
|
|
3
|
+
/**
|
|
4
|
+
* Renders a Vega-Lite chart from a chart template.
|
|
5
|
+
* If dataKey is provided, it merges data from context into the spec.
|
|
6
|
+
* Uses the ChartComponent from FusionFragmentContext if available.
|
|
7
|
+
*/
|
|
8
|
+
export function ChartRenderer({ chart, data, className }) {
|
|
9
|
+
const context = useFusionFragmentContextSafe();
|
|
10
|
+
const ChartComponent = context?.ChartComponent;
|
|
11
|
+
const artifactRunId = context?.artifactRunId;
|
|
12
|
+
// Debug logging
|
|
13
|
+
console.log('[ChartRenderer] Context:', {
|
|
14
|
+
hasContext: !!context,
|
|
15
|
+
hasChartComponent: !!ChartComponent,
|
|
16
|
+
artifactRunId,
|
|
17
|
+
chartTitle: chart.title,
|
|
18
|
+
dataKey: chart.dataKey,
|
|
19
|
+
});
|
|
20
|
+
// Resolve data from context if dataKey is provided
|
|
21
|
+
const resolvedSpec = { ...chart.spec };
|
|
22
|
+
if (chart.dataKey && data[chart.dataKey]) {
|
|
23
|
+
const chartData = data[chart.dataKey];
|
|
24
|
+
if (Array.isArray(chartData)) {
|
|
25
|
+
// Inject data into spec
|
|
26
|
+
resolvedSpec.data = { values: chartData };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Build the VegaLiteChartSpec format expected by @vertesia/ui
|
|
30
|
+
const vegaSpec = {
|
|
31
|
+
library: 'vega-lite',
|
|
32
|
+
title: chart.title,
|
|
33
|
+
description: chart.description,
|
|
34
|
+
spec: resolvedSpec,
|
|
35
|
+
options: {
|
|
36
|
+
height: chart.height,
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
// If a ChartComponent is provided via context, use it to render the actual chart
|
|
40
|
+
if (ChartComponent) {
|
|
41
|
+
return (_jsx("div", { className: className, children: _jsx(ChartComponent, { spec: vegaSpec, artifactRunId: artifactRunId }) }));
|
|
42
|
+
}
|
|
43
|
+
// Fallback: render a placeholder with spec info when no ChartComponent is injected
|
|
44
|
+
return (_jsxs("div", { className: className, style: {
|
|
45
|
+
padding: '16px',
|
|
46
|
+
backgroundColor: 'var(--gray-2, #f9fafb)',
|
|
47
|
+
border: '1px solid var(--gray-5, #e5e7eb)',
|
|
48
|
+
borderRadius: '8px',
|
|
49
|
+
minHeight: chart.height || 280
|
|
50
|
+
}, children: [chart.title && (_jsx("div", { style: {
|
|
51
|
+
fontSize: '14px',
|
|
52
|
+
fontWeight: 600,
|
|
53
|
+
marginBottom: '8px',
|
|
54
|
+
color: 'var(--gray-12, #111827)'
|
|
55
|
+
}, children: chart.title })), chart.description && (_jsx("div", { style: {
|
|
56
|
+
fontSize: '12px',
|
|
57
|
+
color: 'var(--gray-11, #6b7280)',
|
|
58
|
+
marginBottom: '12px'
|
|
59
|
+
}, children: chart.description })), _jsx("div", { style: {
|
|
60
|
+
display: 'flex',
|
|
61
|
+
alignItems: 'center',
|
|
62
|
+
justifyContent: 'center',
|
|
63
|
+
height: (chart.height || 280) - 60,
|
|
64
|
+
backgroundColor: 'var(--gray-3, #f3f4f6)',
|
|
65
|
+
borderRadius: '4px',
|
|
66
|
+
color: 'var(--gray-11, #6b7280)',
|
|
67
|
+
fontSize: '12px'
|
|
68
|
+
}, "data-vega-spec": JSON.stringify(vegaSpec), children: _jsxs("div", { style: { textAlign: 'center' }, children: [_jsxs("div", { style: { marginBottom: '4px' }, children: ["Chart: ", resolvedSpec.mark ? String(typeof resolvedSpec.mark === 'string' ? resolvedSpec.mark : resolvedSpec.mark.type) : 'composite'] }), resolvedSpec.data?.values && (_jsxs("div", { style: { fontSize: '11px', opacity: 0.8 }, children: [resolvedSpec.data.values.length, " data points"] }))] }) })] }));
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=ChartRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChartRenderer.js","sourceRoot":"","sources":["../../../src/fusion-fragment/ChartRenderer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* FieldRenderer component
|
|
4
|
+
* Renders a single field with formatting and optional edit capability
|
|
5
|
+
*/
|
|
6
|
+
import { useMemo, useState, useCallback } from 'react';
|
|
7
|
+
// Styles as constants
|
|
8
|
+
const styles = {
|
|
9
|
+
container: {
|
|
10
|
+
display: 'flex',
|
|
11
|
+
flexDirection: 'column',
|
|
12
|
+
gap: '2px',
|
|
13
|
+
minWidth: 0, // Allow text truncation
|
|
14
|
+
},
|
|
15
|
+
label: {
|
|
16
|
+
fontSize: '11px',
|
|
17
|
+
fontWeight: 500,
|
|
18
|
+
color: 'var(--gray-11, #6b7280)',
|
|
19
|
+
textTransform: 'uppercase',
|
|
20
|
+
letterSpacing: '0.5px',
|
|
21
|
+
},
|
|
22
|
+
value: {
|
|
23
|
+
fontSize: '14px',
|
|
24
|
+
fontWeight: 500,
|
|
25
|
+
color: 'var(--gray-12, #1f2937)',
|
|
26
|
+
fontFamily: 'var(--font-mono, ui-monospace, monospace)',
|
|
27
|
+
fontVariantNumeric: 'tabular-nums',
|
|
28
|
+
letterSpacing: '-0.02em',
|
|
29
|
+
},
|
|
30
|
+
unit: {
|
|
31
|
+
fontSize: '12px',
|
|
32
|
+
color: 'var(--gray-10, #9ca3af)',
|
|
33
|
+
marginLeft: '4px',
|
|
34
|
+
},
|
|
35
|
+
highlight: {
|
|
36
|
+
success: { color: 'var(--green-11, #15803d)' },
|
|
37
|
+
warning: { color: 'var(--yellow-11, #ca8a04)' },
|
|
38
|
+
error: { color: 'var(--red-11, #dc2626)' },
|
|
39
|
+
info: { color: 'var(--blue-11, #2563eb)' },
|
|
40
|
+
},
|
|
41
|
+
editable: {
|
|
42
|
+
cursor: 'pointer',
|
|
43
|
+
padding: '2px 4px',
|
|
44
|
+
borderRadius: '4px',
|
|
45
|
+
transition: 'background-color 0.15s',
|
|
46
|
+
},
|
|
47
|
+
tooltip: {
|
|
48
|
+
position: 'relative',
|
|
49
|
+
},
|
|
50
|
+
nullValue: {
|
|
51
|
+
color: 'var(--gray-9, #9ca3af)',
|
|
52
|
+
fontStyle: 'italic',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Format a value according to the field's format specification
|
|
57
|
+
*/
|
|
58
|
+
function formatValue(value, field) {
|
|
59
|
+
if (value === null || value === undefined) {
|
|
60
|
+
return '\u2014'; // em-dash for null/undefined
|
|
61
|
+
}
|
|
62
|
+
switch (field.format) {
|
|
63
|
+
case 'number': {
|
|
64
|
+
const num = typeof value === 'number' ? value : parseFloat(String(value));
|
|
65
|
+
if (isNaN(num))
|
|
66
|
+
return String(value);
|
|
67
|
+
const options = {
|
|
68
|
+
minimumFractionDigits: field.decimals ?? 0,
|
|
69
|
+
maximumFractionDigits: field.decimals ?? 2,
|
|
70
|
+
};
|
|
71
|
+
return new Intl.NumberFormat('en-US', options).format(num);
|
|
72
|
+
}
|
|
73
|
+
case 'currency': {
|
|
74
|
+
const num = typeof value === 'number' ? value : parseFloat(String(value));
|
|
75
|
+
if (isNaN(num))
|
|
76
|
+
return String(value);
|
|
77
|
+
const options = {
|
|
78
|
+
style: 'currency',
|
|
79
|
+
currency: field.currency || 'USD',
|
|
80
|
+
minimumFractionDigits: field.decimals ?? 0,
|
|
81
|
+
maximumFractionDigits: field.decimals ?? 0,
|
|
82
|
+
};
|
|
83
|
+
return new Intl.NumberFormat('en-US', options).format(num);
|
|
84
|
+
}
|
|
85
|
+
case 'percent': {
|
|
86
|
+
const num = typeof value === 'number' ? value : parseFloat(String(value));
|
|
87
|
+
if (isNaN(num))
|
|
88
|
+
return String(value);
|
|
89
|
+
// Assume value is already a percentage (e.g., 25 for 25%)
|
|
90
|
+
// If it's a decimal (e.g., 0.25), multiply by 100
|
|
91
|
+
const pct = num < 1 && num > -1 && num !== 0 ? num * 100 : num;
|
|
92
|
+
const decimals = field.decimals ?? 1;
|
|
93
|
+
return `${pct.toFixed(decimals)}%`;
|
|
94
|
+
}
|
|
95
|
+
case 'date': {
|
|
96
|
+
if (!value)
|
|
97
|
+
return '\u2014';
|
|
98
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
99
|
+
if (isNaN(date.getTime()))
|
|
100
|
+
return String(value);
|
|
101
|
+
return new Intl.DateTimeFormat('en-US', {
|
|
102
|
+
year: 'numeric',
|
|
103
|
+
month: 'short',
|
|
104
|
+
day: 'numeric',
|
|
105
|
+
}).format(date);
|
|
106
|
+
}
|
|
107
|
+
case 'boolean': {
|
|
108
|
+
const bool = typeof value === 'boolean' ? value : value === 'true' || value === '1';
|
|
109
|
+
return bool ? 'Yes' : 'No';
|
|
110
|
+
}
|
|
111
|
+
case 'text':
|
|
112
|
+
default:
|
|
113
|
+
return String(value);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* FieldRenderer component
|
|
118
|
+
* Displays a field with label, formatted value, and optional highlighting
|
|
119
|
+
*/
|
|
120
|
+
export function FieldRenderer({ field, value, onUpdate, agentMode, }) {
|
|
121
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
122
|
+
const formattedValue = useMemo(() => formatValue(value, field), [value, field]);
|
|
123
|
+
const isNull = value === null || value === undefined;
|
|
124
|
+
const isEditable = field.editable && (onUpdate || agentMode);
|
|
125
|
+
const handleClick = useCallback(() => {
|
|
126
|
+
if (!isEditable)
|
|
127
|
+
return;
|
|
128
|
+
if (agentMode?.enabled && agentMode.sendMessage) {
|
|
129
|
+
// Send message to agent for editing
|
|
130
|
+
agentMode.sendMessage(`Please help me update the "${field.label}" field (key: ${field.key}). Current value: ${formattedValue}`);
|
|
131
|
+
}
|
|
132
|
+
// Direct edit mode would go here (Phase 2)
|
|
133
|
+
}, [isEditable, agentMode, field, formattedValue]);
|
|
134
|
+
const valueStyle = useMemo(() => {
|
|
135
|
+
const base = { ...styles.value };
|
|
136
|
+
if (isNull) {
|
|
137
|
+
return { ...base, ...styles.nullValue };
|
|
138
|
+
}
|
|
139
|
+
if (field.highlight) {
|
|
140
|
+
return { ...base, ...styles.highlight[field.highlight] };
|
|
141
|
+
}
|
|
142
|
+
if (isEditable) {
|
|
143
|
+
return {
|
|
144
|
+
...base,
|
|
145
|
+
...styles.editable,
|
|
146
|
+
backgroundColor: isHovered ? 'var(--gray-3, #f3f4f6)' : 'transparent',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return base;
|
|
150
|
+
}, [isNull, field.highlight, isEditable, isHovered]);
|
|
151
|
+
return (_jsxs("div", { style: styles.container, title: field.tooltip, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onClick: handleClick, role: isEditable ? 'button' : undefined, tabIndex: isEditable ? 0 : undefined, children: [_jsx("span", { style: styles.label, children: field.label }), _jsxs("span", { style: valueStyle, children: [formattedValue, field.unit && !isNull && (_jsx("span", { style: styles.unit, children: field.unit }))] })] }));
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=FieldRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldRenderer.js","sourceRoot":"","sources":["../../../src/fusion-fragment/FieldRenderer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Context provider for FusionFragment components
|
|
4
|
+
* Provides data and update handlers to nested components
|
|
5
|
+
*/
|
|
6
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
7
|
+
const FusionFragmentContext = createContext(null);
|
|
8
|
+
/**
|
|
9
|
+
* Provider component that supplies data and update handlers
|
|
10
|
+
* to FusionFragment components via context
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <FusionFragmentProvider
|
|
15
|
+
* data={fund.parameters}
|
|
16
|
+
* onUpdate={async (key, value) => {
|
|
17
|
+
* await api.funds.updateParameters(fundId, { [key]: value });
|
|
18
|
+
* }}
|
|
19
|
+
* >
|
|
20
|
+
* <MarkdownRenderer content={agentResponse} />
|
|
21
|
+
* </FusionFragmentProvider>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function FusionFragmentProvider({ data, onUpdate, sendMessage, ChartComponent, artifactRunId, children }) {
|
|
25
|
+
const value = useMemo(() => ({ data, onUpdate, sendMessage, ChartComponent, artifactRunId }), [data, onUpdate, sendMessage, ChartComponent, artifactRunId]);
|
|
26
|
+
// Debug logging
|
|
27
|
+
console.log('[FusionFragmentProvider] Created with:', {
|
|
28
|
+
hasData: !!data,
|
|
29
|
+
dataKeys: data ? Object.keys(data) : [],
|
|
30
|
+
hasChartComponent: !!ChartComponent,
|
|
31
|
+
artifactRunId,
|
|
32
|
+
});
|
|
33
|
+
return (_jsx(FusionFragmentContext.Provider, { value: value, children: children }));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Hook to access FusionFragment context
|
|
37
|
+
* @throws Error if used outside of FusionFragmentProvider
|
|
38
|
+
*/
|
|
39
|
+
export function useFusionFragmentContext() {
|
|
40
|
+
const context = useContext(FusionFragmentContext);
|
|
41
|
+
if (!context) {
|
|
42
|
+
throw new Error('useFusionFragmentContext must be used within a FusionFragmentProvider');
|
|
43
|
+
}
|
|
44
|
+
return context;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Hook to safely access FusionFragment context
|
|
48
|
+
* Returns null if not within a provider (useful for optional context)
|
|
49
|
+
*/
|
|
50
|
+
export function useFusionFragmentContextSafe() {
|
|
51
|
+
return useContext(FusionFragmentContext);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=FusionFragmentContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FusionFragmentContext.js","sourceRoot":"","sources":["../../../src/fusion-fragment/FusionFragmentContext.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAqC,MAAM,OAAO,CAAC;AAG9F,MAAM,qBAAqB,GAAG,aAAa,CAAoC,IAAI,CAAC,CAAC;AAiBrF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,cAAc,EACd,aAAa,EACb,QAAQ,EACoB;IAC5B,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC,EACtE,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,CAAC,CAC7D,CAAC;IAEF,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE;QACpD,OAAO,EAAE,CAAC,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;QACvC,iBAAiB,EAAE,CAAC,CAAC,cAAc;QACnC,aAAa;KACd,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,qBAAqB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACzC,QAAQ,GACsB,CAClC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,MAAM,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAElD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO,UAAU,CAAC,qBAAqB,CAAC,CAAC;AAC3C,CAAC"}
|