@seed-ship/mcp-ui-solid 6.19.1 → 6.21.0
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/CHANGELOG.md +663 -0
- package/README.md +911 -4
- package/dist/adapters/connector.cjs +15 -4
- package/dist/adapters/connector.cjs.map +1 -1
- package/dist/adapters/connector.d.ts +38 -0
- package/dist/adapters/connector.d.ts.map +1 -1
- package/dist/adapters/connector.js +15 -4
- package/dist/adapters/connector.js.map +1 -1
- package/dist/adapters/index.d.ts +4 -3
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/macro-run.cjs +25 -13
- package/dist/adapters/macro-run.cjs.map +1 -1
- package/dist/adapters/macro-run.d.ts +37 -2
- package/dist/adapters/macro-run.d.ts.map +1 -1
- package/dist/adapters/macro-run.js +25 -13
- package/dist/adapters/macro-run.js.map +1 -1
- package/dist/adapters.cjs +2 -0
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.js +4 -2
- package/dist/components/ActionGroupRenderer.cjs +3 -1
- package/dist/components/ActionGroupRenderer.cjs.map +1 -1
- package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
- package/dist/components/ActionGroupRenderer.js +3 -1
- package/dist/components/ActionGroupRenderer.js.map +1 -1
- package/dist/components/AgentCard.cjs +11 -8
- package/dist/components/AgentCard.cjs.map +1 -1
- package/dist/components/AgentCard.d.ts.map +1 -1
- package/dist/components/AgentCard.js +11 -8
- package/dist/components/AgentCard.js.map +1 -1
- package/dist/components/AgentHandoff.cjs +6 -1
- package/dist/components/AgentHandoff.cjs.map +1 -1
- package/dist/components/AgentHandoff.d.ts.map +1 -1
- package/dist/components/AgentHandoff.js +6 -1
- package/dist/components/AgentHandoff.js.map +1 -1
- package/dist/components/ArtifactRenderer.cjs +25 -6
- package/dist/components/ArtifactRenderer.cjs.map +1 -1
- package/dist/components/ArtifactRenderer.d.ts.map +1 -1
- package/dist/components/ArtifactRenderer.js +25 -6
- package/dist/components/ArtifactRenderer.js.map +1 -1
- package/dist/components/AutocompleteDropdown.cjs +30 -24
- package/dist/components/AutocompleteDropdown.cjs.map +1 -1
- package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
- package/dist/components/AutocompleteDropdown.js +30 -24
- package/dist/components/AutocompleteDropdown.js.map +1 -1
- package/dist/components/AutocompleteFormField.cjs +3 -1
- package/dist/components/AutocompleteFormField.cjs.map +1 -1
- package/dist/components/AutocompleteFormField.d.ts.map +1 -1
- package/dist/components/AutocompleteFormField.js +4 -2
- package/dist/components/AutocompleteFormField.js.map +1 -1
- package/dist/components/BriefingDiff.cjs +45 -39
- package/dist/components/BriefingDiff.cjs.map +1 -1
- package/dist/components/BriefingDiff.d.ts.map +1 -1
- package/dist/components/BriefingDiff.js +45 -39
- package/dist/components/BriefingDiff.js.map +1 -1
- package/dist/components/CarouselRenderer.cjs +8 -2
- package/dist/components/CarouselRenderer.cjs.map +1 -1
- package/dist/components/CarouselRenderer.d.ts.map +1 -1
- package/dist/components/CarouselRenderer.js +8 -2
- package/dist/components/CarouselRenderer.js.map +1 -1
- package/dist/components/ChartJSRenderer.cjs +60 -36
- package/dist/components/ChartJSRenderer.cjs.map +1 -1
- package/dist/components/ChartJSRenderer.d.ts.map +1 -1
- package/dist/components/ChartJSRenderer.js +61 -37
- package/dist/components/ChartJSRenderer.js.map +1 -1
- package/dist/components/ChatPrompt.cjs +15 -9
- package/dist/components/ChatPrompt.cjs.map +1 -1
- package/dist/components/ChatPrompt.d.ts.map +1 -1
- package/dist/components/ChatPrompt.js +15 -9
- package/dist/components/ChatPrompt.js.map +1 -1
- package/dist/components/CodeBlockRenderer.cjs +34 -16
- package/dist/components/CodeBlockRenderer.cjs.map +1 -1
- package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/components/CodeBlockRenderer.js +34 -16
- package/dist/components/CodeBlockRenderer.js.map +1 -1
- package/dist/components/DataPreviewSection.cjs +91 -44
- package/dist/components/DataPreviewSection.cjs.map +1 -1
- package/dist/components/DataPreviewSection.d.ts.map +1 -1
- package/dist/components/DataPreviewSection.js +92 -45
- package/dist/components/DataPreviewSection.js.map +1 -1
- package/dist/components/DegradedFallback.cjs +20 -16
- package/dist/components/DegradedFallback.cjs.map +1 -1
- package/dist/components/DegradedFallback.d.ts.map +1 -1
- package/dist/components/DegradedFallback.js +20 -16
- package/dist/components/DegradedFallback.js.map +1 -1
- package/dist/components/FooterRenderer.cjs +21 -17
- package/dist/components/FooterRenderer.cjs.map +1 -1
- package/dist/components/FooterRenderer.d.ts.map +1 -1
- package/dist/components/FooterRenderer.js +21 -17
- package/dist/components/FooterRenderer.js.map +1 -1
- package/dist/components/FormFieldRenderer.cjs +116 -93
- package/dist/components/FormFieldRenderer.cjs.map +1 -1
- package/dist/components/FormFieldRenderer.d.ts.map +1 -1
- package/dist/components/FormFieldRenderer.js +116 -93
- package/dist/components/FormFieldRenderer.js.map +1 -1
- package/dist/components/FormRenderer.cjs +55 -31
- package/dist/components/FormRenderer.cjs.map +1 -1
- package/dist/components/FormRenderer.d.ts.map +1 -1
- package/dist/components/FormRenderer.js +55 -31
- package/dist/components/FormRenderer.js.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js +20 -15
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
- package/dist/components/GraphRenderer.cjs +56 -33
- package/dist/components/GraphRenderer.cjs.map +1 -1
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +56 -33
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/IframeFallbackLink.cjs +37 -0
- package/dist/components/IframeFallbackLink.cjs.map +1 -0
- package/dist/components/IframeFallbackLink.d.ts +23 -0
- package/dist/components/IframeFallbackLink.d.ts.map +1 -0
- package/dist/components/IframeFallbackLink.js +37 -0
- package/dist/components/IframeFallbackLink.js.map +1 -0
- package/dist/components/ImageGalleryRenderer.cjs +13 -4
- package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
- package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
- package/dist/components/ImageGalleryRenderer.js +13 -4
- package/dist/components/ImageGalleryRenderer.js.map +1 -1
- package/dist/components/LightboxOverlay.cjs +16 -8
- package/dist/components/LightboxOverlay.cjs.map +1 -1
- package/dist/components/LightboxOverlay.d.ts.map +1 -1
- package/dist/components/LightboxOverlay.js +17 -9
- package/dist/components/LightboxOverlay.js.map +1 -1
- package/dist/components/MapRenderer.cjs +59 -29
- package/dist/components/MapRenderer.cjs.map +1 -1
- package/dist/components/MapRenderer.d.ts +10 -2
- package/dist/components/MapRenderer.d.ts.map +1 -1
- package/dist/components/MapRenderer.js +60 -30
- package/dist/components/MapRenderer.js.map +1 -1
- package/dist/components/ModalRenderer.cjs +4 -1
- package/dist/components/ModalRenderer.cjs.map +1 -1
- package/dist/components/ModalRenderer.d.ts.map +1 -1
- package/dist/components/ModalRenderer.js +5 -2
- package/dist/components/ModalRenderer.js.map +1 -1
- package/dist/components/ScratchpadPanel.cjs +578 -535
- package/dist/components/ScratchpadPanel.cjs.map +1 -1
- package/dist/components/ScratchpadPanel.d.ts.map +1 -1
- package/dist/components/ScratchpadPanel.js +578 -535
- package/dist/components/ScratchpadPanel.js.map +1 -1
- package/dist/components/StreamingUIRenderer.cjs +92 -28
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +92 -28
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +481 -365
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts +21 -0
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +484 -368
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/components/VerifiedText.cjs +39 -20
- package/dist/components/VerifiedText.cjs.map +1 -1
- package/dist/components/VerifiedText.d.ts +2 -1
- package/dist/components/VerifiedText.d.ts.map +1 -1
- package/dist/components/VerifiedText.js +39 -20
- package/dist/components/VerifiedText.js.map +1 -1
- package/dist/components/VideoRenderer.cjs +51 -20
- package/dist/components/VideoRenderer.cjs.map +1 -1
- package/dist/components/VideoRenderer.d.ts.map +1 -1
- package/dist/components/VideoRenderer.js +51 -20
- package/dist/components/VideoRenderer.js.map +1 -1
- package/dist/components/chart-data-table.cjs +38 -17
- package/dist/components/chart-data-table.cjs.map +1 -1
- package/dist/components/chart-data-table.d.ts +30 -1
- package/dist/components/chart-data-table.d.ts.map +1 -1
- package/dist/components/chart-data-table.js +38 -17
- package/dist/components/chart-data-table.js.map +1 -1
- package/dist/context/MCPActionContext.cjs +3 -1
- package/dist/context/MCPActionContext.cjs.map +1 -1
- package/dist/context/MCPActionContext.d.ts.map +1 -1
- package/dist/context/MCPActionContext.js +3 -1
- package/dist/context/MCPActionContext.js.map +1 -1
- package/dist/context/MCPUIConfigContext.cjs +29 -0
- package/dist/context/MCPUIConfigContext.cjs.map +1 -0
- package/dist/context/MCPUIConfigContext.d.ts +124 -0
- package/dist/context/MCPUIConfigContext.d.ts.map +1 -0
- package/dist/context/MCPUIConfigContext.js +29 -0
- package/dist/context/MCPUIConfigContext.js.map +1 -0
- package/dist/context/MCPUIStringsContext.cjs +287 -2
- package/dist/context/MCPUIStringsContext.cjs.map +1 -1
- package/dist/context/MCPUIStringsContext.d.ts +607 -3
- package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
- package/dist/context/MCPUIStringsContext.js +287 -2
- package/dist/context/MCPUIStringsContext.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.cjs +28 -10
- package/dist/hooks/useStreamingUI.cjs.map +1 -1
- package/dist/hooks/useStreamingUI.d.ts +37 -0
- package/dist/hooks/useStreamingUI.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.js +28 -10
- package/dist/hooks/useStreamingUI.js.map +1 -1
- package/dist/hooks.cjs +1 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +2 -1
- package/dist/index.cjs +29 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/validation.cjs +52 -26
- package/dist/services/validation.cjs.map +1 -1
- package/dist/services/validation.d.ts +67 -2
- package/dist/services/validation.d.ts.map +1 -1
- package/dist/services/validation.js +52 -26
- package/dist/services/validation.js.map +1 -1
- package/dist/utils/degraded-projections.cjs +37 -12
- package/dist/utils/degraded-projections.cjs.map +1 -1
- package/dist/utils/degraded-projections.d.ts +39 -3
- package/dist/utils/degraded-projections.d.ts.map +1 -1
- package/dist/utils/degraded-projections.js +37 -12
- package/dist/utils/degraded-projections.js.map +1 -1
- package/dist/utils/format-string.cjs +10 -0
- package/dist/utils/format-string.cjs.map +1 -0
- package/dist/utils/format-string.d.ts +26 -0
- package/dist/utils/format-string.d.ts.map +1 -0
- package/dist/utils/format-string.js +10 -0
- package/dist/utils/format-string.js.map +1 -0
- package/dist/utils/iframe-coep.cjs +30 -0
- package/dist/utils/iframe-coep.cjs.map +1 -0
- package/dist/utils/iframe-coep.d.ts +46 -0
- package/dist/utils/iframe-coep.d.ts.map +1 -0
- package/dist/utils/iframe-coep.js +30 -0
- package/dist/utils/iframe-coep.js.map +1 -0
- package/dist/validation.cjs +5 -0
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.cts +2 -1
- package/dist/validation.d.ts +2 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +6 -1
- package/package.json +1 -1
- package/src/adapters/connector.ts +58 -4
- package/src/adapters/index.ts +12 -2
- package/src/adapters/macro-run.ts +71 -11
- package/src/components/ActionGroupRenderer.tsx +3 -1
- package/src/components/AgentCard.tsx +27 -9
- package/src/components/AgentHandoff.tsx +4 -1
- package/src/components/ArtifactRenderer.tsx +17 -5
- package/src/components/AutocompleteDropdown.tsx +8 -6
- package/src/components/AutocompleteFormField.tsx +5 -1
- package/src/components/BriefingDiff.tsx +11 -3
- package/src/components/CarouselRenderer.tsx +4 -2
- package/src/components/ChartJSRenderer.tsx +18 -9
- package/src/components/ChatPrompt.tsx +13 -8
- package/src/components/CodeBlockRenderer.tsx +12 -10
- package/src/components/DataPreviewSection.tsx +92 -26
- package/src/components/DegradedFallback.tsx +4 -2
- package/src/components/FooterRenderer.tsx +3 -1
- package/src/components/FormFieldRenderer.tsx +34 -19
- package/src/components/FormRenderer.tsx +38 -10
- package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
- package/src/components/GraphRenderer.tsx +31 -16
- package/src/components/IframeFallbackLink.tsx +57 -0
- package/src/components/ImageGalleryRenderer.tsx +8 -4
- package/src/components/LightboxOverlay.tsx +6 -4
- package/src/components/MapRenderer.tsx +57 -20
- package/src/components/ModalRenderer.tsx +3 -1
- package/src/components/ScratchpadPanel.tsx +95 -44
- package/src/components/StreamingUIRenderer.tsx +41 -11
- package/src/components/UIResourceRenderer.tsx +176 -67
- package/src/components/VerifiedText.tsx +19 -9
- package/src/components/VideoRenderer.tsx +26 -4
- package/src/components/chart-data-table.ts +68 -14
- package/src/context/MCPActionContext.tsx +4 -1
- package/src/context/MCPUIConfigContext.tsx +151 -0
- package/src/context/MCPUIStringsContext.tsx +1014 -1
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useStreamingUI.ts +64 -10
- package/src/index.ts +38 -0
- package/src/services/index.ts +1 -0
- package/src/services/validation.ts +131 -32
- package/src/solid-jsx-attrs.d.ts +24 -0
- package/src/utils/degraded-projections.ts +75 -12
- package/src/utils/format-string.ts +33 -0
- package/src/utils/iframe-coep.ts +74 -0
- package/src/validation.ts +9 -0
package/src/adapters/index.ts
CHANGED
|
@@ -14,13 +14,23 @@
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
export {
|
|
17
|
+
export {
|
|
18
|
+
connectorResultToUILayout,
|
|
19
|
+
connectorActionsToActionGroup,
|
|
20
|
+
DEFAULT_CONNECTOR_MESSAGES,
|
|
21
|
+
} from './connector';
|
|
18
22
|
export type {
|
|
19
23
|
ConnectorResultToUILayoutOptions,
|
|
20
24
|
ConnectorActionsToActionGroupOptions,
|
|
25
|
+
ConnectorAdapterMessages,
|
|
21
26
|
} from './connector';
|
|
22
27
|
|
|
23
|
-
export {
|
|
28
|
+
export {
|
|
29
|
+
macroRunToScratchpadState,
|
|
30
|
+
macroInterrogationToChatPromptConfig,
|
|
31
|
+
DEFAULT_MACRO_RUN_MESSAGES,
|
|
32
|
+
} from './macro-run';
|
|
33
|
+
export type { MacroRunAdapterMessages, MacroRunAdapterOptions } from './macro-run';
|
|
24
34
|
|
|
25
35
|
export {
|
|
26
36
|
createComparisonLayout,
|
|
@@ -174,7 +174,59 @@ function resultSectionType(componentType: unknown): ScratchpadSection['type'] {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
/**
|
|
178
|
+
* The English wording this adapter produces on its own — section titles and
|
|
179
|
+
* the fallbacks used when the run (or the interrogation) carries none.
|
|
180
|
+
*
|
|
181
|
+
* The adapter is runtime-free by contract: no `solid-js`, no
|
|
182
|
+
* `MCPUIStringsContext`. Hosts that render in another language pass a
|
|
183
|
+
* partial override through `MacroRunAdapterOptions.messages`, exactly like
|
|
184
|
+
* `ConnectorResultToUILayoutOptions.messages`.
|
|
185
|
+
*
|
|
186
|
+
* @since v6.20.0
|
|
187
|
+
*/
|
|
188
|
+
export interface MacroRunAdapterMessages {
|
|
189
|
+
/** Title of the always-present `agent_card` section. */
|
|
190
|
+
agentSectionTitle: string;
|
|
191
|
+
/** Title of the `stepper` / `split_stepper` section. */
|
|
192
|
+
progressSectionTitle: string;
|
|
193
|
+
/** Title of each result section. */
|
|
194
|
+
resultSectionTitle: string;
|
|
195
|
+
/** Error message of an aborted run that carries no `error`. */
|
|
196
|
+
runAborted: string;
|
|
197
|
+
/** Error message of a failed run that carries no `error`. */
|
|
198
|
+
runFailed: string;
|
|
199
|
+
/** Prompt body of an elicitation with no usable schema and no message. */
|
|
200
|
+
confirmDefault: string;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** English defaults for {@link MacroRunAdapterMessages}. */
|
|
204
|
+
export const DEFAULT_MACRO_RUN_MESSAGES: MacroRunAdapterMessages = {
|
|
205
|
+
agentSectionTitle: 'Agent',
|
|
206
|
+
progressSectionTitle: 'Progress',
|
|
207
|
+
resultSectionTitle: 'Result',
|
|
208
|
+
runAborted: 'Macro run aborted.',
|
|
209
|
+
runFailed: 'Macro run failed.',
|
|
210
|
+
confirmDefault: 'Please confirm to continue.',
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
/** Options shared by the MacroRun adapters. @since v6.20.0 */
|
|
214
|
+
export interface MacroRunAdapterOptions {
|
|
215
|
+
/**
|
|
216
|
+
* Partial override of the adapter's own wording, merged over
|
|
217
|
+
* {@link DEFAULT_MACRO_RUN_MESSAGES}.
|
|
218
|
+
*/
|
|
219
|
+
messages?: Partial<MacroRunAdapterMessages>;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const withMessages = (
|
|
223
|
+
options: MacroRunAdapterOptions = {}
|
|
224
|
+
): MacroRunAdapterMessages => ({ ...DEFAULT_MACRO_RUN_MESSAGES, ...options.messages });
|
|
225
|
+
|
|
226
|
+
function buildError(
|
|
227
|
+
run: MacroRunV1,
|
|
228
|
+
messages: MacroRunAdapterMessages
|
|
229
|
+
): ScratchpadState['error'] | undefined {
|
|
178
230
|
if (run.status !== 'failed' && run.status !== 'aborted') return undefined;
|
|
179
231
|
const aborted = run.status === 'aborted';
|
|
180
232
|
if (run.error) {
|
|
@@ -187,7 +239,7 @@ function buildError(run: MacroRunV1): ScratchpadState['error'] | undefined {
|
|
|
187
239
|
return err;
|
|
188
240
|
}
|
|
189
241
|
return {
|
|
190
|
-
message: aborted ?
|
|
242
|
+
message: aborted ? messages.runAborted : messages.runFailed,
|
|
191
243
|
retryable: false,
|
|
192
244
|
};
|
|
193
245
|
}
|
|
@@ -209,13 +261,17 @@ function buildError(run: MacroRunV1): ScratchpadState['error'] | undefined {
|
|
|
209
261
|
*
|
|
210
262
|
* Pure: no fetch, no SSE, no persistence. The host owns all wiring.
|
|
211
263
|
*/
|
|
212
|
-
export function macroRunToScratchpadState(
|
|
264
|
+
export function macroRunToScratchpadState(
|
|
265
|
+
run: MacroRunV1,
|
|
266
|
+
options: MacroRunAdapterOptions = {}
|
|
267
|
+
): ScratchpadState {
|
|
268
|
+
const messages = withMessages(options);
|
|
213
269
|
const sections: ScratchpadSection[] = [];
|
|
214
270
|
|
|
215
271
|
// 1. Agent card — always present.
|
|
216
272
|
sections.push({
|
|
217
273
|
id: 'macro-agent',
|
|
218
|
-
title:
|
|
274
|
+
title: messages.agentSectionTitle,
|
|
219
275
|
type: 'agent_card',
|
|
220
276
|
content: buildAgentCard(run),
|
|
221
277
|
editable: false,
|
|
@@ -229,7 +285,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
229
285
|
hasParallel
|
|
230
286
|
? {
|
|
231
287
|
id: 'macro-split-stepper',
|
|
232
|
-
title:
|
|
288
|
+
title: messages.progressSectionTitle,
|
|
233
289
|
type: 'split_stepper',
|
|
234
290
|
content: buildSplitStepperContent(run.steps),
|
|
235
291
|
editable: false,
|
|
@@ -237,7 +293,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
237
293
|
}
|
|
238
294
|
: {
|
|
239
295
|
id: 'macro-stepper',
|
|
240
|
-
title:
|
|
296
|
+
title: messages.progressSectionTitle,
|
|
241
297
|
type: 'stepper',
|
|
242
298
|
content: buildStepperContent(run.steps),
|
|
243
299
|
editable: false,
|
|
@@ -252,7 +308,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
252
308
|
id: 'macro-prompt',
|
|
253
309
|
title: run.pendingInterrogation.title,
|
|
254
310
|
type: 'prompt',
|
|
255
|
-
content: macroInterrogationToChatPromptConfig(run.pendingInterrogation),
|
|
311
|
+
content: macroInterrogationToChatPromptConfig(run.pendingInterrogation, options),
|
|
256
312
|
editable: false,
|
|
257
313
|
source: 'agent',
|
|
258
314
|
});
|
|
@@ -265,7 +321,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
265
321
|
results.forEach((component, index) => {
|
|
266
322
|
sections.push({
|
|
267
323
|
id: `macro-result-${String(component?.id ?? index)}`,
|
|
268
|
-
title:
|
|
324
|
+
title: messages.resultSectionTitle,
|
|
269
325
|
type: resultSectionType(component?.type),
|
|
270
326
|
content: component,
|
|
271
327
|
editable: false,
|
|
@@ -282,7 +338,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
282
338
|
status: RUN_STATUS_TO_SCRATCHPAD[run.status],
|
|
283
339
|
};
|
|
284
340
|
|
|
285
|
-
const error = buildError(run);
|
|
341
|
+
const error = buildError(run, messages);
|
|
286
342
|
if (error) state.error = error;
|
|
287
343
|
|
|
288
344
|
return state;
|
|
@@ -311,7 +367,11 @@ function isElicitationSchema(value: unknown): value is ElicitationRequestedSchem
|
|
|
311
367
|
* {@link macroRunToScratchpadState} (which calls it for an embedded
|
|
312
368
|
* `pendingInterrogation`).
|
|
313
369
|
*/
|
|
314
|
-
export function macroInterrogationToChatPromptConfig(
|
|
370
|
+
export function macroInterrogationToChatPromptConfig(
|
|
371
|
+
q: MacroInterrogationV1,
|
|
372
|
+
options: MacroRunAdapterOptions = {}
|
|
373
|
+
): ChatPromptConfig {
|
|
374
|
+
const messages = withMessages(options);
|
|
315
375
|
switch (q.kind) {
|
|
316
376
|
case 'choice': {
|
|
317
377
|
const options: ChoiceOption[] = (q.options ?? []).map((o) => {
|
|
@@ -355,7 +415,7 @@ export function macroInterrogationToChatPromptConfig(q: MacroInterrogationV1): C
|
|
|
355
415
|
return {
|
|
356
416
|
type: 'confirm',
|
|
357
417
|
title: q.title,
|
|
358
|
-
config: { message: q.message ??
|
|
418
|
+
config: { message: q.message ?? messages.confirmDefault },
|
|
359
419
|
};
|
|
360
420
|
}
|
|
361
421
|
}
|
|
@@ -7,6 +7,7 @@ import { Component, For, Show } from 'solid-js'
|
|
|
7
7
|
import type { UIComponent, ActionGroupParams, ActionComponentParams } from '../types'
|
|
8
8
|
import { useAction } from '../hooks/useAction'
|
|
9
9
|
import { safeUrl } from '../utils/safe-url'
|
|
10
|
+
import { useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
10
11
|
|
|
11
12
|
export interface ActionGroupRendererProps {
|
|
12
13
|
/**
|
|
@@ -147,6 +148,7 @@ const ActionButton: Component<{
|
|
|
147
148
|
* ```
|
|
148
149
|
*/
|
|
149
150
|
export const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props) => {
|
|
151
|
+
const strings = useMCPUIStrings()
|
|
150
152
|
const params = () => props.params || (props.component?.params as ActionGroupParams) || { actions: [] }
|
|
151
153
|
|
|
152
154
|
const layoutClass = () => {
|
|
@@ -181,7 +183,7 @@ export const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props)
|
|
|
181
183
|
<div
|
|
182
184
|
class={`${layoutClass()} ${gapClass()} ${params()?.fullWidth ? 'w-full' : ''}`}
|
|
183
185
|
role="group"
|
|
184
|
-
aria-label={params()?.label ||
|
|
186
|
+
aria-label={params()?.label || strings.actionGroupLabel}
|
|
185
187
|
>
|
|
186
188
|
<For each={params()?.actions || []}>
|
|
187
189
|
{(action, index) => <ActionButton action={action} index={index()} />}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { Show, For } from 'solid-js'
|
|
9
9
|
import type { AgentCardContent } from '../types/chat-bus'
|
|
10
|
+
import { useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
10
11
|
|
|
11
12
|
export interface AgentCardProps {
|
|
12
13
|
content: AgentCardContent
|
|
@@ -23,15 +24,31 @@ const AVATAR_MAP: Record<string, string> = {
|
|
|
23
24
|
robot: '\uD83E\uDD16',
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Status styling. The record stays module-level, but it carries a
|
|
29
|
+
* `labelKey` rather than English: the label is resolved from
|
|
30
|
+
* `useMCPUIStrings()` at render time so a host provider can localize it.
|
|
31
|
+
*/
|
|
32
|
+
type AgentStatusLabelKey =
|
|
33
|
+
| 'agentStatusIdle'
|
|
34
|
+
| 'agentStatusRunning'
|
|
35
|
+
| 'agentStatusWaiting'
|
|
36
|
+
| 'agentStatusDone'
|
|
37
|
+
| 'agentStatusError'
|
|
38
|
+
|
|
39
|
+
const STATUS_CONFIG: Record<
|
|
40
|
+
string,
|
|
41
|
+
{ labelKey: AgentStatusLabelKey; color: string; pulse: boolean }
|
|
42
|
+
> = {
|
|
43
|
+
idle: { labelKey: 'agentStatusIdle', color: 'bg-gray-400', pulse: false },
|
|
44
|
+
running: { labelKey: 'agentStatusRunning', color: 'bg-blue-500', pulse: true },
|
|
45
|
+
waiting: { labelKey: 'agentStatusWaiting', color: 'bg-amber-500', pulse: true },
|
|
46
|
+
done: { labelKey: 'agentStatusDone', color: 'bg-green-500', pulse: false },
|
|
47
|
+
error: { labelKey: 'agentStatusError', color: 'bg-red-500', pulse: false },
|
|
32
48
|
}
|
|
33
49
|
|
|
34
50
|
export function AgentCard(props: AgentCardProps) {
|
|
51
|
+
const strings = useMCPUIStrings()
|
|
35
52
|
const c = () => props.content
|
|
36
53
|
const status = () => STATUS_CONFIG[c().status] || STATUS_CONFIG.idle
|
|
37
54
|
const avatar = () => AVATAR_MAP[c().avatar || ''] || c().avatar || '\uD83E\uDD16'
|
|
@@ -54,8 +71,8 @@ export function AgentCard(props: AgentCardProps) {
|
|
|
54
71
|
<div class="flex items-center gap-2">
|
|
55
72
|
<span class="font-medium text-sm text-gray-900 dark:text-white truncate">{c().name}</span>
|
|
56
73
|
{/* Status dot */}
|
|
57
|
-
<span class={`inline-block w-2 h-2 rounded-full ${status().color} ${status().pulse ? 'animate-pulse' : ''}`} title={status().
|
|
58
|
-
<span class="text-xs text-gray-500 dark:text-gray-400">{status().
|
|
74
|
+
<span class={`inline-block w-2 h-2 rounded-full ${status().color} ${status().pulse ? 'animate-pulse' : ''}`} title={strings[status().labelKey]} />
|
|
75
|
+
<span class="text-xs text-gray-500 dark:text-gray-400">{strings[status().labelKey]}</span>
|
|
59
76
|
</div>
|
|
60
77
|
|
|
61
78
|
{/* Model */}
|
|
@@ -97,13 +114,14 @@ export interface AgentStatusBadgeProps {
|
|
|
97
114
|
}
|
|
98
115
|
|
|
99
116
|
export function AgentStatusBadge(props: AgentStatusBadgeProps) {
|
|
117
|
+
const strings = useMCPUIStrings()
|
|
100
118
|
const status = () => STATUS_CONFIG[props.status] || STATUS_CONFIG.idle
|
|
101
119
|
|
|
102
120
|
return (
|
|
103
121
|
<span class="inline-flex items-center gap-1.5 text-xs">
|
|
104
122
|
<span class={`w-2 h-2 rounded-full ${status().color} ${status().pulse ? 'animate-pulse' : ''}`} />
|
|
105
123
|
<span class="text-gray-600 dark:text-gray-300">{props.agentName}</span>
|
|
106
|
-
<span class="text-gray-400 dark:text-gray-500">{status().
|
|
124
|
+
<span class="text-gray-400 dark:text-gray-500">{strings[status().labelKey]}</span>
|
|
107
125
|
</span>
|
|
108
126
|
)
|
|
109
127
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { Show } from 'solid-js'
|
|
9
9
|
import type { AgentHandoffContent } from '../types/chat-bus'
|
|
10
|
+
import { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
10
11
|
|
|
11
12
|
export interface AgentHandoffProps {
|
|
12
13
|
content: AgentHandoffContent
|
|
@@ -24,6 +25,7 @@ function getAvatar(key?: string): string {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export function AgentHandoff(props: AgentHandoffProps) {
|
|
28
|
+
const strings = useMCPUIStrings()
|
|
27
29
|
const c = () => props.content
|
|
28
30
|
|
|
29
31
|
if (typeof console !== 'undefined') {
|
|
@@ -49,7 +51,8 @@ export function AgentHandoff(props: AgentHandoffProps) {
|
|
|
49
51
|
</div>
|
|
50
52
|
<Show when={c().summary || c().itemCount}>
|
|
51
53
|
<span class="text-[10px] text-gray-500 dark:text-gray-400 text-center">
|
|
52
|
-
{c().summary ||
|
|
54
|
+
{c().summary ||
|
|
55
|
+
formatMCPUIString(strings.handoffItems, { count: c().itemCount ?? 0 })}
|
|
53
56
|
</span>
|
|
54
57
|
</Show>
|
|
55
58
|
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component } from 'solid-js'
|
|
2
2
|
import { safeUrl } from '../utils/safe-url'
|
|
3
|
+
import { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
3
4
|
|
|
4
5
|
export interface ArtifactComponentParams {
|
|
5
6
|
url: string
|
|
@@ -10,6 +11,7 @@ export interface ArtifactComponentParams {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export const ArtifactRenderer: Component<{ params: ArtifactComponentParams }> = (props) => {
|
|
14
|
+
const strings = useMCPUIStrings()
|
|
13
15
|
const getIcon = () => {
|
|
14
16
|
if (props.params.mimeType?.includes('csv')) return '📊'
|
|
15
17
|
if (props.params.mimeType?.includes('json')) return '{}'
|
|
@@ -19,9 +21,19 @@ export const ArtifactRenderer: Component<{ params: ArtifactComponentParams }> =
|
|
|
19
21
|
|
|
20
22
|
const formatSize = (bytes?: number) => {
|
|
21
23
|
if (!bytes) return ''
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
const oneDecimal = (n: number) =>
|
|
25
|
+
new Intl.NumberFormat(strings.locale, {
|
|
26
|
+
minimumFractionDigits: 1,
|
|
27
|
+
maximumFractionDigits: 1,
|
|
28
|
+
useGrouping: false,
|
|
29
|
+
}).format(n)
|
|
30
|
+
if (bytes < 1024) {
|
|
31
|
+
return formatMCPUIString(strings.sizeBytes, {
|
|
32
|
+
size: new Intl.NumberFormat(strings.locale, { maximumFractionDigits: 0 }).format(bytes),
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
if (bytes < 1024 * 1024) return formatMCPUIString(strings.sizeKilobytes, { size: oneDecimal(bytes / 1024) })
|
|
36
|
+
return formatMCPUIString(strings.sizeMegabytes, { size: oneDecimal(bytes / (1024 * 1024)) })
|
|
25
37
|
}
|
|
26
38
|
|
|
27
39
|
return (
|
|
@@ -35,7 +47,7 @@ export const ArtifactRenderer: Component<{ params: ArtifactComponentParams }> =
|
|
|
35
47
|
{props.params.filename}
|
|
36
48
|
</h4>
|
|
37
49
|
<p class="text-xs text-gray-500 dark:text-gray-400">
|
|
38
|
-
{formatSize(props.params.size)} • {props.params.description ||
|
|
50
|
+
{formatSize(props.params.size)} • {props.params.description || strings.artifactDescription}
|
|
39
51
|
</p>
|
|
40
52
|
</div>
|
|
41
53
|
</div>
|
|
@@ -48,7 +60,7 @@ export const ArtifactRenderer: Component<{ params: ArtifactComponentParams }> =
|
|
|
48
60
|
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
49
61
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
|
50
62
|
</svg>
|
|
51
|
-
|
|
63
|
+
{strings.download}
|
|
52
64
|
</a>
|
|
53
65
|
</div>
|
|
54
66
|
)
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { Component, For, Show, createMemo, JSX } from 'solid-js'
|
|
9
9
|
import type { AutocompleteOption } from '../types'
|
|
10
|
+
import { useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Props for AutocompleteDropdown
|
|
@@ -142,6 +143,7 @@ const DefaultOptionRenderer: Component<{
|
|
|
142
143
|
* AutocompleteDropdown Component
|
|
143
144
|
*/
|
|
144
145
|
export const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props) => {
|
|
146
|
+
const strings = useMCPUIStrings()
|
|
145
147
|
const positionStyles = createMemo((): JSX.CSSProperties => {
|
|
146
148
|
if (props.position === 'top') {
|
|
147
149
|
return {
|
|
@@ -175,7 +177,7 @@ export const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props
|
|
|
175
177
|
class={`mcp-autocomplete-dropdown ${props.class || ''}`}
|
|
176
178
|
style={containerStyles()}
|
|
177
179
|
role="listbox"
|
|
178
|
-
aria-label=
|
|
180
|
+
aria-label={strings.autocompleteSuggestions}
|
|
179
181
|
>
|
|
180
182
|
{/* Loading state */}
|
|
181
183
|
<Show when={props.isLoading}>
|
|
@@ -201,7 +203,7 @@ export const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props
|
|
|
201
203
|
animation: 'mcp-spin 0.6s linear infinite'
|
|
202
204
|
}}
|
|
203
205
|
/>
|
|
204
|
-
{props.loadingMessage ||
|
|
206
|
+
{props.loadingMessage || strings.autocompleteLoading}
|
|
205
207
|
</div>
|
|
206
208
|
</Show>
|
|
207
209
|
|
|
@@ -216,7 +218,7 @@ export const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props
|
|
|
216
218
|
'text-align': 'center'
|
|
217
219
|
}}
|
|
218
220
|
>
|
|
219
|
-
{props.emptyMessage ||
|
|
221
|
+
{props.emptyMessage || strings.autocompleteEmpty}
|
|
220
222
|
</div>
|
|
221
223
|
</Show>
|
|
222
224
|
|
|
@@ -302,7 +304,7 @@ export const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props
|
|
|
302
304
|
'font-family': 'inherit',
|
|
303
305
|
'font-size': '0.7rem'
|
|
304
306
|
}}>↓</kbd>
|
|
305
|
-
{
|
|
307
|
+
{strings.autocompleteHintNavigate}
|
|
306
308
|
<kbd style={{
|
|
307
309
|
'background-color': '#e5e7eb',
|
|
308
310
|
padding: '1px 4px',
|
|
@@ -310,7 +312,7 @@ export const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props
|
|
|
310
312
|
'font-family': 'inherit',
|
|
311
313
|
'font-size': '0.7rem'
|
|
312
314
|
}}>Enter</kbd>
|
|
313
|
-
{
|
|
315
|
+
{strings.autocompleteHintSelect}
|
|
314
316
|
<kbd style={{
|
|
315
317
|
'background-color': '#e5e7eb',
|
|
316
318
|
padding: '1px 4px',
|
|
@@ -318,7 +320,7 @@ export const AutocompleteDropdown: Component<AutocompleteDropdownProps> = (props
|
|
|
318
320
|
'font-family': 'inherit',
|
|
319
321
|
'font-size': '0.7rem'
|
|
320
322
|
}}>Esc</kbd>
|
|
321
|
-
{
|
|
323
|
+
{strings.autocompleteHintDismiss}
|
|
322
324
|
</div>
|
|
323
325
|
</Show>
|
|
324
326
|
</div>
|
|
@@ -10,6 +10,7 @@ import type { FormFieldParams, FieldAutocompleteConfig, AutocompleteContext } fr
|
|
|
10
10
|
import { useConditionalField } from '../hooks/useConditionalField'
|
|
11
11
|
import { useAutocomplete } from '../hooks/useAutocomplete'
|
|
12
12
|
import { useAutocompleteContextSafe } from '../context/AutocompleteContext'
|
|
13
|
+
import { useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
13
14
|
import { GhostText } from './GhostText'
|
|
14
15
|
import { AutocompleteDropdown } from './AutocompleteDropdown'
|
|
15
16
|
|
|
@@ -62,6 +63,7 @@ export interface AutocompleteFormFieldProps {
|
|
|
62
63
|
* AutocompleteFormField Component
|
|
63
64
|
*/
|
|
64
65
|
export const AutocompleteFormField: Component<AutocompleteFormFieldProps> = (props) => {
|
|
66
|
+
const strings = useMCPUIStrings()
|
|
65
67
|
// Check if autocomplete context is available
|
|
66
68
|
const autocompleteCtx = useAutocompleteContextSafe()
|
|
67
69
|
|
|
@@ -205,7 +207,9 @@ export const AutocompleteFormField: Component<AutocompleteFormFieldProps> = (pro
|
|
|
205
207
|
inputValue={localValue()}
|
|
206
208
|
ghostText={autocomplete.ghostText()}
|
|
207
209
|
visible={autocomplete.isOpen()}
|
|
208
|
-
hintText={
|
|
210
|
+
hintText={
|
|
211
|
+
autocomplete.ghostText() ? strings.autocompleteTabToAccept : undefined
|
|
212
|
+
}
|
|
209
213
|
isLoading={autocomplete.isLoading()}
|
|
210
214
|
/>
|
|
211
215
|
</Show>
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { For, Show } from 'solid-js'
|
|
9
9
|
import type { BriefingDiffContent } from '../types/chat-bus'
|
|
10
|
+
import { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
10
11
|
|
|
11
12
|
export interface BriefingDiffProps {
|
|
12
13
|
content: BriefingDiffContent
|
|
@@ -19,6 +20,7 @@ const CHANGE_CONFIG: Record<string, { icon: string; color: string; bg: string }>
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export function BriefingDiff(props: BriefingDiffProps) {
|
|
23
|
+
const strings = useMCPUIStrings()
|
|
22
24
|
const c = () => props.content
|
|
23
25
|
|
|
24
26
|
if (typeof console !== 'undefined') {
|
|
@@ -45,13 +47,19 @@ export function BriefingDiff(props: BriefingDiffProps) {
|
|
|
45
47
|
{(stats) => (
|
|
46
48
|
<div class="flex items-center gap-3 text-xs">
|
|
47
49
|
<Show when={stats().added > 0}>
|
|
48
|
-
<span class="text-green-600 dark:text-green-400"
|
|
50
|
+
<span class="text-green-600 dark:text-green-400">
|
|
51
|
+
{formatMCPUIString(strings.briefingAdded, { count: stats().added })}
|
|
52
|
+
</span>
|
|
49
53
|
</Show>
|
|
50
54
|
<Show when={stats().removed > 0}>
|
|
51
|
-
<span class="text-red-600 dark:text-red-400">
|
|
55
|
+
<span class="text-red-600 dark:text-red-400">
|
|
56
|
+
{formatMCPUIString(strings.briefingRemoved, { count: stats().removed })}
|
|
57
|
+
</span>
|
|
52
58
|
</Show>
|
|
53
59
|
<Show when={stats().changed > 0}>
|
|
54
|
-
<span class="text-amber-600 dark:text-amber-400">
|
|
60
|
+
<span class="text-amber-600 dark:text-amber-400">
|
|
61
|
+
{formatMCPUIString(strings.briefingChanged, { count: stats().changed })}
|
|
62
|
+
</span>
|
|
55
63
|
</Show>
|
|
56
64
|
</div>
|
|
57
65
|
)}
|
|
@@ -3,6 +3,7 @@ import { isServer } from 'solid-js/web'
|
|
|
3
3
|
import { useRenderContext } from './RenderContext'
|
|
4
4
|
import type { UIComponent } from '../types'
|
|
5
5
|
import { ExpandableWrapper, useExpanded } from './ExpandableWrapper'
|
|
6
|
+
import { useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
6
7
|
|
|
7
8
|
export interface CarouselRendererProps {
|
|
8
9
|
items: UIComponent[]
|
|
@@ -15,6 +16,7 @@ export interface CarouselRendererProps {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export const CarouselRenderer: Component<CarouselRendererProps> = (props) => {
|
|
19
|
+
const strings = useMCPUIStrings()
|
|
18
20
|
let scrollContainer: HTMLDivElement | undefined
|
|
19
21
|
const [canScrollLeft, setCanScrollLeft] = createSignal(false)
|
|
20
22
|
const [canScrollRight, setCanScrollRight] = createSignal(true)
|
|
@@ -42,9 +44,9 @@ export const CarouselRenderer: Component<CarouselRendererProps> = (props) => {
|
|
|
42
44
|
|
|
43
45
|
return (
|
|
44
46
|
<ExpandableWrapper
|
|
45
|
-
title={
|
|
47
|
+
title={strings.carouselTitle}
|
|
46
48
|
copyData={JSON.stringify(props.items, null, 2)}
|
|
47
|
-
copyLabel=
|
|
49
|
+
copyLabel={strings.carouselCopy}
|
|
48
50
|
toolbarVariant={props.toolbarVariant}
|
|
49
51
|
>
|
|
50
52
|
<div class={`relative group ${isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''}`}>
|
|
@@ -24,7 +24,7 @@ import { ExpandableWrapper, useExpanded } from './ExpandableWrapper';
|
|
|
24
24
|
import { DegradedFallback } from './DegradedFallback';
|
|
25
25
|
import { chartToDataTable } from './chart-data-table';
|
|
26
26
|
import { useTelemetry } from '../context/MCPUITelemetryContext';
|
|
27
|
-
import { useMCPUIStrings } from '../context/MCPUIStringsContext';
|
|
27
|
+
import { formatMCPUIString, useMCPUIStrings } from '../context/MCPUIStringsContext';
|
|
28
28
|
|
|
29
29
|
// Lazy load Chart.js to avoid bundling if not used
|
|
30
30
|
let ChartJS: any = null;
|
|
@@ -113,9 +113,18 @@ export const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {
|
|
|
113
113
|
let renderVersion = 0;
|
|
114
114
|
|
|
115
115
|
const params = () => props.component.params as ChartComponentParams;
|
|
116
|
-
const tableData = createMemo(() => chartToDataTable(params()));
|
|
117
116
|
const telemetry = useTelemetry();
|
|
118
117
|
const strings = useMCPUIStrings();
|
|
118
|
+
// The accessible data table is a pure projection: its column headers come
|
|
119
|
+
// from the chrome strings, injected rather than hardcoded in the helper.
|
|
120
|
+
const tableData = createMemo(() =>
|
|
121
|
+
chartToDataTable(params(), {
|
|
122
|
+
series: strings.chartTableSeries,
|
|
123
|
+
point: strings.chartTablePoint,
|
|
124
|
+
label: strings.degradedColLabel,
|
|
125
|
+
seriesName: strings.degradedSeries,
|
|
126
|
+
})
|
|
127
|
+
);
|
|
119
128
|
const descriptionId = createUniqueId();
|
|
120
129
|
const title = () => params().title || strings.chartView;
|
|
121
130
|
|
|
@@ -205,7 +214,7 @@ export const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {
|
|
|
205
214
|
setIsLoading(false);
|
|
206
215
|
} catch (err) {
|
|
207
216
|
if (version !== renderVersion) return;
|
|
208
|
-
const error = err instanceof Error ? err : new Error(
|
|
217
|
+
const error = err instanceof Error ? err : new Error(strings.chartRenderError);
|
|
209
218
|
setError(error.message);
|
|
210
219
|
setIsLoading(false);
|
|
211
220
|
// Fallback ladder (P2.5): record the failure so it's observable, then
|
|
@@ -241,7 +250,7 @@ export const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {
|
|
|
241
250
|
<ExpandableWrapper
|
|
242
251
|
title={title()}
|
|
243
252
|
copyData={copyDataJSON()}
|
|
244
|
-
copyLabel=
|
|
253
|
+
copyLabel={strings.chartCopy}
|
|
245
254
|
toolbarVariant={props.toolbarVariant}
|
|
246
255
|
>
|
|
247
256
|
<ContextAwareChartLayout
|
|
@@ -294,8 +303,8 @@ export const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {
|
|
|
294
303
|
onClick={handleExportPNG}
|
|
295
304
|
disabled={activeView() !== 'chart' || isLoading() || Boolean(error())}
|
|
296
305
|
class="opacity-0 group-hover:opacity-60 hover:!opacity-100 disabled:!opacity-30 disabled:cursor-not-allowed px-2 py-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm"
|
|
297
|
-
title=
|
|
298
|
-
aria-label=
|
|
306
|
+
title={strings.chartDownloadPng}
|
|
307
|
+
aria-label={strings.chartDownloadPngAria}
|
|
299
308
|
>
|
|
300
309
|
<svg
|
|
301
310
|
class="w-3 h-3 text-gray-500 dark:text-gray-400"
|
|
@@ -323,8 +332,8 @@ export const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {
|
|
|
323
332
|
instead of a bare "Chart Error" message. */}
|
|
324
333
|
<Show when={error() && activeView() === 'chart'}>
|
|
325
334
|
<DegradedFallback
|
|
326
|
-
message={
|
|
327
|
-
caption=
|
|
335
|
+
message={formatMCPUIString(strings.chartRenderFailed, { error: String(error()) })}
|
|
336
|
+
caption={strings.chartDegradedCaption}
|
|
328
337
|
{...tableData()}
|
|
329
338
|
/>
|
|
330
339
|
</Show>
|
|
@@ -405,7 +414,7 @@ export const ChartJSRenderer: Component<ChartJSRendererProps> = (props) => {
|
|
|
405
414
|
<div class="absolute inset-0 flex items-center justify-center bg-white/80 dark:bg-gray-800/80">
|
|
406
415
|
<div class="flex flex-col items-center gap-2">
|
|
407
416
|
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" />
|
|
408
|
-
<span class="text-sm text-gray-500 dark:text-gray-400">
|
|
417
|
+
<span class="text-sm text-gray-500 dark:text-gray-400">{strings.chartLoading}</span>
|
|
409
418
|
</div>
|
|
410
419
|
</div>
|
|
411
420
|
</Show>
|