@jini-ai/ui 0.5.5 → 0.6.10
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 +91 -2
- package/dist/core/theme/validation.js +40 -38
- package/dist/features/a2ui/renderer.js +15 -13
- package/dist/features/about/react/components/AboutTab.js +64 -34
- package/dist/features/about/rules.d.ts +2 -2
- package/dist/features/about/rules.js +156 -129
- package/dist/features/admin-widgets/components/ImagePreviewModal.d.ts +4 -3
- package/dist/features/admin-widgets/components/ImagePreviewModal.js +6 -10
- package/dist/features/admin-widgets/components/InfoTip.d.ts +3 -2
- package/dist/features/admin-widgets/components/InfoTip.hooks.js +2 -0
- package/dist/features/admin-widgets/components/InfoTip.js +34 -7
- package/dist/features/admin-widgets/components/InfoTip.rules.d.ts +13 -0
- package/dist/features/admin-widgets/components/InfoTip.rules.js +43 -10
- package/dist/features/admin-widgets/components/Lightbox/Lightbox.d.ts +30 -0
- package/dist/features/admin-widgets/components/Lightbox/Lightbox.hooks.d.ts +40 -0
- package/dist/features/admin-widgets/components/Lightbox/Lightbox.hooks.js +128 -0
- package/dist/features/admin-widgets/components/Lightbox/Lightbox.js +18 -0
- package/dist/features/admin-widgets/components/MiddleTruncate.d.ts +14 -0
- package/dist/features/admin-widgets/components/MiddleTruncate.js +12 -0
- package/dist/features/admin-widgets/components/MiddleTruncate.rules.d.ts +20 -0
- package/dist/features/admin-widgets/components/MiddleTruncate.rules.js +21 -0
- package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.d.ts +18 -0
- package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.hooks.d.ts +16 -0
- package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.hooks.js +45 -0
- package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.js +18 -0
- package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.rules.d.ts +32 -0
- package/dist/features/admin-widgets/components/ScrollJump/ScrollJump.rules.js +26 -0
- package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.hooks.js +29 -14
- package/dist/features/admin-widgets/index.d.ts +14 -2
- package/dist/features/admin-widgets/index.js +7 -1
- package/dist/features/admin-widgets/styles/admin-widgets.css +1 -0
- package/dist/features/asset-grid/react/components/AssetCard.js +7 -1
- package/dist/features/asset-grid/react/components/AssetGrid.d.ts +1 -1
- package/dist/features/asset-grid/react/components/AssetGrid.js +38 -18
- package/dist/features/asset-grid/react/components/useAssetGridFilters.d.ts +21 -0
- package/dist/features/asset-grid/react/components/useAssetGridFilters.js +19 -0
- package/dist/features/asset-grid/react/hooks/useAssetGridKeyboardShortcuts.js +16 -11
- package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.d.ts +2 -0
- package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.js +35 -11
- package/dist/features/asset-tree-browser/react/components/AssetTreeBrowser.d.ts +6 -6
- package/dist/features/asset-tree-browser/react/components/AssetTreeBrowser.js +10 -129
- package/dist/features/asset-tree-browser/react/components/AssetTreeBrowserParts.d.ts +50 -0
- package/dist/features/asset-tree-browser/react/components/AssetTreeBrowserParts.js +95 -0
- package/dist/features/asset-tree-browser/react/components/useAssetTreeBrowserController.d.ts +56 -0
- package/dist/features/asset-tree-browser/react/components/useAssetTreeBrowserController.js +80 -0
- package/dist/features/asset-tree-browser/rules.js +40 -22
- package/dist/features/browser-chrome/rules.js +74 -70
- package/dist/features/charts/browser.js +11 -5
- package/dist/features/charts/react.js +2 -2
- package/dist/features/charts/table.js +2 -2
- package/dist/features/command-palette/react/hooks/useCommandPalette.js +3 -9
- package/dist/features/connectors/ConnectorsBrowser.d.ts +4 -4
- package/dist/features/connectors/ConnectorsBrowser.js +26 -14
- package/dist/features/connectors/components/ConnectorCard.js +67 -38
- package/dist/features/connectors/components/ConnectorDetailDrawer.js +62 -31
- package/dist/features/connectors/components/ConnectorGrid.js +11 -6
- package/dist/features/connectors/hooks/useConnectorAuthorization.js +6 -0
- package/dist/features/connectors/hooks/useConnectorCatalog.d.ts +2 -0
- package/dist/features/connectors/hooks/useConnectorCatalog.js +32 -13
- package/dist/features/connectors/hooks/useWiredConnectorsBrowser.d.ts +3 -3
- package/dist/features/connectors/rules.d.ts +8 -1
- package/dist/features/connectors/rules.js +42 -20
- package/dist/features/connectors/types.d.ts +11 -0
- package/dist/features/execution/constants.d.ts +4 -10
- package/dist/features/execution/constants.js +9 -94
- package/dist/features/execution/react/components/ByokProviderForm.d.ts +2 -4
- package/dist/features/execution/react/components/ByokProviderForm.js +140 -43
- package/dist/features/execution/react/components/ExecutionTab.d.ts +1 -2
- package/dist/features/execution/react/components/ExecutionTab.js +52 -30
- package/dist/features/execution/react/components/LocalCliAgentCard.js +12 -3
- package/dist/features/execution/react/components/LocalCliAgentList.js +14 -3
- package/dist/features/execution/react/components/LocalCliAgentSettings.js +14 -3
- package/dist/features/execution/react/hooks/useLocalCliAgentCard.js +54 -36
- package/dist/features/execution/react/hooks/useReasoningControl.js +114 -78
- package/dist/features/execution/rules.d.ts +2 -2
- package/dist/features/execution/rules.js +31 -15
- package/dist/features/execution/types.d.ts +4 -42
- package/dist/features/execution/types.js +0 -17
- package/dist/features/external-mcp/react/components/ExternalMcpTab.d.ts +6 -2
- package/dist/features/external-mcp/react/components/ExternalMcpTab.js +9 -2
- package/dist/features/file-dropzone/react/components/FileDropzone.js +24 -25
- package/dist/features/file-dropzone/react/components/FileDropzoneLightbox.d.ts +2 -2
- package/dist/features/file-dropzone/react/components/FileDropzoneLightbox.js +35 -30
- package/dist/features/file-dropzone/react/components/FileDropzoneThumbnailGrid.js +30 -24
- package/dist/features/file-dropzone/react/components/FileDropzoneZone.d.ts +14 -0
- package/dist/features/file-dropzone/react/components/FileDropzoneZone.js +26 -0
- package/dist/features/html-editor/canvas-content-wrapper.js +13 -13
- package/dist/features/html-editor/canvas-embed-placeholders.js +46 -37
- package/dist/features/html-editor/css.js +76 -69
- package/dist/features/html-editor/editor-blocks.js +47 -33
- package/dist/features/html-editor/editor-serialization.js +6 -5
- package/dist/features/html-editor/protected-elements.js +39 -28
- package/dist/features/html-editor/react/hooks/useInteractiveHtmlEditor.js +4 -4
- package/dist/features/html-editor/source-splice.js +51 -30
- package/dist/features/i18n/dictionaries/settings-dialog.ja.js +1 -0
- package/dist/features/i18n/dictionaries/settings-dialog.zh-CN.js +1 -0
- package/dist/features/i18n/dictionaries/settings-dialog.zh-TW.js +1 -0
- package/dist/features/i18n/locale.js +20 -16
- package/dist/features/iframe-pool/react/dom-sync.js +8 -6
- package/dist/features/integrations/react/components/CodexInstallToggleButton.js +19 -4
- package/dist/features/integrations/react/components/IntegrationsTab.js +60 -14
- package/dist/features/interactive-ui/interactive-ui.css +1 -1
- package/dist/features/interactive-ui/providers/shadcn/data-table.js +10 -7
- package/dist/features/lexical-rich-text-editor/mention-parser.js +60 -57
- package/dist/features/lexical-rich-text-editor/react/hooks/useKeyboardCommands.js +33 -38
- package/dist/features/lexical-rich-text-editor/rules.js +87 -74
- package/dist/features/lexical-rich-text-editor/serialize.js +27 -25
- package/dist/features/mcp-ui/secret-card.js +111 -61
- package/dist/features/mcp-ui/surfaces/confirmation.js +39 -21
- package/dist/features/mcp-ui/surfaces/document.d.ts +1 -1
- package/dist/features/mcp-ui/surfaces/document.js +10 -2
- package/dist/features/mcp-ui/surfaces/fields.js +30 -50
- package/dist/features/mcp-ui/surfaces/form.d.ts +6 -0
- package/dist/features/mcp-ui/surfaces/form.js +43 -21
- package/dist/features/mcp-ui/surfaces/outcome.js +30 -20
- package/dist/features/mcp-ui/surfaces/text-input.js +33 -21
- package/dist/features/mcp-ui/surfaces/tokens.d.ts +6 -1
- package/dist/features/mcp-ui/surfaces/tokens.js +5 -2
- package/dist/features/media-providers/constants.d.ts +1 -0
- package/dist/features/media-providers/constants.js +2 -81
- package/dist/features/media-providers/index.d.ts +1 -1
- package/dist/features/media-providers/ports.d.ts +2 -0
- package/dist/features/media-providers/react/components/MediaProviderCard.d.ts +22 -0
- package/dist/features/media-providers/react/components/MediaProviderCard.js +50 -0
- package/dist/features/media-providers/react/components/MediaProvidersTab.d.ts +5 -6
- package/dist/features/media-providers/react/components/MediaProvidersTab.js +40 -72
- package/dist/features/media-providers/react/components/media-providers-tab-labels.d.ts +11 -0
- package/dist/features/media-providers/react/components/media-providers-tab-labels.js +57 -0
- package/dist/features/media-providers/react/hooks/useMediaProvidersTab.d.ts +4 -2
- package/dist/features/media-providers/react/hooks/useMediaProvidersTab.js +37 -23
- package/dist/features/media-providers/rules.js +17 -10
- package/dist/features/media-providers/types.d.ts +4 -22
- package/dist/features/media-providers/types.js +3 -8
- package/dist/features/memory/formatters.js +127 -92
- package/dist/features/memory/react/components/MemoryConnectedPanel.js +92 -36
- package/dist/features/memory/react/components/MemoryList.js +37 -18
- package/dist/features/memory/react/hooks/useMemoryExtractions.store.js +42 -36
- package/dist/features/notifications/react/components/NotificationsTab.js +28 -28
- package/dist/features/observability/long-task.d.ts +0 -12
- package/dist/features/observability/long-task.js +15 -19
- package/dist/features/observability/resource-error.d.ts +0 -10
- package/dist/features/observability/resource-error.js +18 -13
- package/dist/features/observability/stuck-run.js +10 -6
- package/dist/features/observability/telemetry-url.d.ts +6 -0
- package/dist/features/observability/telemetry-url.js +16 -0
- package/dist/features/observability/white-screen.js +12 -24
- package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +2 -2
- package/dist/features/panel-kit/fetch-query/adapter.react.js +4 -2
- package/dist/features/panel-kit/fetch-query/adapter.tanstack.js +46 -33
- package/dist/features/panel-kit/helpers/standing-draft-local-backup.js +3 -1
- package/dist/features/panel-kit/hooks/use-settings-slice.hooks.js +3 -1
- package/dist/features/privacy/react/components/PrivacyTab.js +24 -13
- package/dist/features/progress-card/components/ProgressCard.js +7 -3
- package/dist/features/progress-card/reference-adapters.js +59 -54
- package/dist/features/project-locations/react/components/ProjectLocationsTab.js +24 -15
- package/dist/features/project-locations/react/hooks/useProjectLocationsTab.d.ts +8 -0
- package/dist/features/project-locations/react/hooks/useProjectLocationsTab.js +31 -23
- package/dist/features/resource-dashboard/react/components/ResourceBoard.js +6 -47
- package/dist/features/resource-dashboard/react/components/ResourceBoardView.d.ts +2 -2
- package/dist/features/resource-dashboard/react/components/ResourceBoardView.js +3 -6
- package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.d.ts +15 -0
- package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.js +35 -0
- package/dist/features/resource-dashboard/react/components/ResourceCard.js +5 -16
- package/dist/features/resource-dashboard/react/components/ResourceCardParts.d.ts +34 -0
- package/dist/features/resource-dashboard/react/components/ResourceCardParts.js +34 -0
- package/dist/features/resource-dashboard/react/components/ResourceRowList.js +3 -1
- package/dist/features/resource-dashboard/react/components/ResourceRowListItem.js +2 -2
- package/dist/features/resource-dashboard/react/components/ResourceRowListItemParts.d.ts +19 -0
- package/dist/features/resource-dashboard/react/components/ResourceRowListItemParts.js +11 -0
- package/dist/features/resource-dashboard/react/components/ResourceRowListView.d.ts +1 -1
- package/dist/features/resource-dashboard/react/components/ResourceRowListView.js +4 -4
- package/dist/features/resource-dashboard/react/components/ResourceRowListViewParts.d.ts +10 -0
- package/dist/features/resource-dashboard/react/components/ResourceRowListViewParts.js +20 -0
- package/dist/features/resource-dashboard/react/components/resourceBoardProps.d.ts +48 -0
- package/dist/features/resource-dashboard/react/components/resourceBoardProps.js +70 -0
- package/dist/features/resource-dashboard/react/components/resourceRowListProps.d.ts +19 -0
- package/dist/features/resource-dashboard/react/components/resourceRowListProps.js +14 -0
- package/dist/features/resource-dashboard/react/components/translatedErrorLabelProps.d.ts +16 -0
- package/dist/features/resource-dashboard/react/components/translatedErrorLabelProps.js +13 -0
- package/dist/features/resource-dashboard/rules.js +2 -8
- package/dist/features/sketch-editor/dom.js +150 -99
- package/dist/features/sketch-editor/react/components/SketchEditor.js +26 -15
- package/dist/features/skills/react/components/SkillDraftForm.js +13 -19
- package/dist/features/skills/react/components/SkillDraftForm.labels.d.ts +31 -0
- package/dist/features/skills/react/components/SkillDraftForm.labels.js +54 -0
- package/dist/features/skills/react/components/SkillRow.js +38 -18
- package/dist/features/skills/react/components/SkillRow.labels.d.ts +7 -0
- package/dist/features/skills/react/components/SkillRow.labels.js +18 -0
- package/dist/features/skills/react/components/SkillsTab.js +24 -14
- package/dist/features/skills/react/components/SkillsTab.labels.d.ts +7 -0
- package/dist/features/skills/react/components/SkillsTab.labels.js +11 -0
- package/dist/features/skills/rules.js +32 -23
- package/dist/features/source-config-list/agent-handles.js +2 -1
- package/dist/features/source-config-list/dependencies.js +53 -49
- package/dist/features/source-config-list/index.d.ts +3 -3
- package/dist/features/source-config-list/react/components/SourceConfigAddForm.d.ts +6 -5
- package/dist/features/source-config-list/react/components/SourceConfigAddForm.js +38 -7
- package/dist/features/source-config-list/react/components/SourceConfigField.js +69 -25
- package/dist/features/source-config-list/react/components/SourceConfigItemCard.d.ts +6 -5
- package/dist/features/source-config-list/react/components/SourceConfigItemCard.js +76 -20
- package/dist/features/source-config-list/react/components/SourceConfigListView.d.ts +5 -3
- package/dist/features/source-config-list/react/components/SourceConfigListView.js +33 -3
- package/dist/features/source-config-list/react/components/SourceConfigTestControl.js +17 -1
- package/dist/features/source-config-list/react/components/SourceConfigTrustOptions.d.ts +11 -0
- package/dist/features/source-config-list/react/components/SourceConfigTrustOptions.js +12 -0
- package/dist/features/source-config-list/types.d.ts +14 -0
- package/dist/features/tab-launcher-menu/react/components/TabLauncherMenu.js +25 -1
- package/dist/features/tab-launcher-menu/react/hooks/useTabLauncherMenu.js +15 -16
- package/dist/features/tab-strip/react/components/TabBar.js +8 -1
- package/dist/features/tabbed-dialog/react/components/TabbedDialog.js +8 -30
- package/dist/features/tabbed-dialog/react/components/TabbedDialogChrome.d.ts +15 -0
- package/dist/features/tabbed-dialog/react/components/TabbedDialogChrome.js +8 -0
- package/dist/features/tabbed-dialog/react/components/TabbedDialogHeader.d.ts +12 -0
- package/dist/features/tabbed-dialog/react/components/TabbedDialogHeader.js +6 -0
- package/dist/features/tabbed-dialog/react/components/TabbedDialogSidebar.d.ts +27 -0
- package/dist/features/tabbed-dialog/react/components/TabbedDialogSidebar.js +12 -0
- package/dist/features/tabbed-dialog/react/components/tabbedDialogView.d.ts +43 -0
- package/dist/features/tabbed-dialog/react/components/tabbedDialogView.js +59 -0
- package/dist/features/version-manager/dependencies.d.ts +3 -1
- package/dist/features/version-manager/dependencies.js +3 -2
- package/dist/features/version-manager/react/components/VersionManagerModal.js +10 -6
- package/dist/features/version-manager/react/hooks/useVersionManager.js +7 -4
- package/dist/features/viewer-shell/react/components/CommentSidePanel.js +103 -50
- package/dist/features/viewer-shell/react/components/MarkdownSplitPane.js +28 -8
- package/dist/features/viewer-shell/react/hooks/useCommentReorder.js +22 -16
- package/dist/features/viewer-shell/rules.js +19 -23
- package/dist/react/components/CustomSelect.d.ts +38 -1
- package/dist/react/components/CustomSelect.js +94 -38
- package/dist/react/components/OnboardingDropdown.js +20 -8
- package/dist/react/components/RemixIcon.stylesheet.js +3 -1
- package/dist/react/components/Toast.js +13 -2
- package/dist/react/components/TooltipLayer.js +5 -14
- package/dist/react/components/WorkingDirPicker.js +78 -50
- package/dist/react/components/remixicon-font-recovery.js +38 -30
- package/dist/react/components/select-popover.d.ts +8 -6
- package/dist/react/components/select-popover.js +33 -29
- package/dist/react/mcp-ui/McpUiHost.d.ts +1 -1
- package/dist/react/mcp-ui/McpUiHost.js +10 -11
- package/dist/react/mcp-ui/host-message-source.d.ts +14 -2
- package/dist/react/mcp-ui/host-message-source.js +15 -5
- package/dist/react/mcp-ui/mcp-ui-host-frame.d.ts +41 -0
- package/dist/react/mcp-ui/mcp-ui-host-frame.js +39 -0
- package/dist/renderers/annotation-canvas/react/components/AnnotationCanvas.js +97 -69
- package/dist/renderers/preview-modal-shell/react/components/PreviewModalShell.js +59 -30
- package/dist/renderers/react/components/ArtifactView.js +9 -6
- package/dist/renderers/srcdoc/build.d.ts +4 -1
- package/dist/renderers/srcdoc/build.js +62 -48
- package/dist/styles/admin.css +29 -14
- package/dist/styles/lightbox.css +142 -0
- package/dist/styles/variables.css +128 -0
- package/dist/theme/apply.js +9 -5
- package/dist/utils/auto-open-file.d.ts +2 -1
- package/dist/utils/auto-open-file.js +69 -85
- package/dist/utils/markdown-scroll-sync.js +108 -87
- package/dist/utils/polygon-selection.js +25 -26
- package/dist/utils/smooth-scroll-to-top.d.ts +1 -1
- package/dist/utils/smooth-scroll-to-top.js +2 -32
- package/dist/utils/sse.js +26 -26
- package/dist/utils/unit-bezier.d.ts +7 -0
- package/dist/utils/unit-bezier.js +38 -0
- package/package.json +9 -12
- package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.d.ts +0 -13
- package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.js +0 -46
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,96 @@
|
|
|
1
1
|
# @jini-ai/ui
|
|
2
2
|
|
|
3
|
+
## 0.6.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 72ea04d: Folded `@jini-ai/renderers-react` into `@jini-ai/ui` as an independently-importable, tree-shakeable
|
|
8
|
+
`./renderers` subpath, and retired the package.
|
|
9
|
+
|
|
10
|
+
Real (non-comment) imports of `@jini-ai/renderers-react` anywhere in the repo were exactly 3 files,
|
|
11
|
+
2 symbols, all inside `@jini-ai/ui`'s own `features/html-viewer` — `openSandboxedPreviewInNewTab`
|
|
12
|
+
and `useSandboxBridge`. `@jini-ai/ui` was already the package's only real consumer, so a standalone
|
|
13
|
+
package bought nothing, the same reasoning that folded `@jini-ai/ui-core` into `./core` and
|
|
14
|
+
`@jini-ai/composio` into `@jini-ai/admin`. The whole `src/**` tree (registry, renderers, srcDoc
|
|
15
|
+
host, annotation-canvas, preview-modal-shell, i18n) moves to `packages/ui/src/renderers/` as one
|
|
16
|
+
`git mv`, unchanged in shape; `html-viewer`'s two consumers switch from the package-qualified
|
|
17
|
+
import to a relative one, since they're now in the same package.
|
|
18
|
+
|
|
19
|
+
**The `@jini-ai/renderers-react → @jini-ai/chat` dependency was dropped first, before the move,
|
|
20
|
+
not after.** `registry.ts` imported `ArtifactManifest`/`inferLegacyManifest` from `@jini-ai/chat`,
|
|
21
|
+
and `types.ts` re-exported five manifest types from there. `@jini-ai/chat` already depends on
|
|
22
|
+
`@jini-ai/ui`, so folding renderers-react into `ui` unchanged would have created a real `ui ↔ chat`
|
|
23
|
+
package cycle. The five manifest types (`ArtifactManifest`, `ArtifactKind`, `ArtifactRendererId`,
|
|
24
|
+
`ArtifactExportKind`, `ArtifactStatus`) are now defined locally in `types.ts`, copied verbatim from
|
|
25
|
+
`@jini-ai/chat`'s `src/core/util/types.ts` — a small duplicated-type cost, accepted because a
|
|
26
|
+
renderer package must not depend on a chat package.
|
|
27
|
+
|
|
28
|
+
**`resolveArtifactManifest` no longer infers a legacy manifest from a file's name/extension** — a
|
|
29
|
+
real, disclosed API behavior change. It now returns `file.manifest ?? null`. Manifest inference
|
|
30
|
+
(guessing kind/renderer from `.md`/`.html`/`.svg`/`.tsx`, etc.) is a caller concern that depends on
|
|
31
|
+
a product's own naming conventions, not something a generic renderer registry should do on a
|
|
32
|
+
caller's behalf; a caller that still wants that inference should resolve a manifest for the file
|
|
33
|
+
itself (see `@jini-ai/chat`'s `inferLegacyManifest`) before handing it to this registry. Verified
|
|
34
|
+
zero external callers of `RendererRegistry`/`resolveArtifactManifest`/`createDefaultRendererRegistry`
|
|
35
|
+
anywhere in Jini or Tovu before making this change — `@jini-ai/chat`'s own `RendererRegistry` is an
|
|
36
|
+
unrelated, locally-defined class in `artifact-types.ts`, and `@jini-ai/artifacts`' own
|
|
37
|
+
`resolveArtifactManifest` is an unrelated 3-argument function; both are same-name coincidences, not
|
|
38
|
+
real dependents. The four bundled renderers (`HtmlRenderer`, `MarkdownRenderer`, `SvgRenderer`,
|
|
39
|
+
`ReactComponentRenderer`) gate `canRender` on a resolvable manifest before falling back to any
|
|
40
|
+
`file.kind`/extension heuristic of their own, so this ripples into every test that exercised
|
|
41
|
+
default-registry routing via a bare file name with no explicit `manifest` — all updated to attach
|
|
42
|
+
one, with the extension-inference-specific assertions flipped to assert the removed behavior no
|
|
43
|
+
longer fires. No test was weakened or deleted: every changed assertion now tests the new,
|
|
44
|
+
documented contract, or restores a manifest to keep testing what it always meant to test.
|
|
45
|
+
|
|
46
|
+
**`@jini-ai/renderers-react` is retired, not versioned forward.** It was published (0.1.2), and
|
|
47
|
+
`packages/renderers-react` is deleted from this workspace. Deleting the source does not unpublish
|
|
48
|
+
anything, so whoever runs the next release should follow up with:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
npm deprecate @jini-ai/renderers-react "Merged into @jini-ai/ui; import from '@jini-ai/ui/renderers' instead."
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`@jini-ai/chat`'s dead `@jini-ai/renderers-react` dependency (declared, never imported — its own
|
|
55
|
+
`react/artifact-types.ts` defines a local placeholder registry instead, per its
|
|
56
|
+
`TODO(renderers-react)` header, left untouched here as out of scope) is removed from its
|
|
57
|
+
`package.json`, hence the accompanying patch bump.
|
|
58
|
+
|
|
59
|
+
- 4082999: Folded `@jini-ai/ui-core` into `@jini-ai/ui` as an independently-importable `./core` subpath.
|
|
60
|
+
|
|
61
|
+
`ui-core` was never a standalone concern — it was always the framework-free half (types, decision
|
|
62
|
+
rules, catalogs, host port contracts; no React, no DOM) of `@jini-ai/ui`'s own features, published
|
|
63
|
+
separately only because that pairing was undiscoverable without reading both trees side by side.
|
|
64
|
+
All 13 `ui-core` features move to their same-named `@jini-ai/ui` feature directory, alongside the
|
|
65
|
+
React half they were always paired with; `@jini-ai/ui/core` (`src/core.ts`) is the new entry point
|
|
66
|
+
that re-exports exactly what `@jini-ai/ui-core`'s own root barrel did. `react`/`react-dom` move
|
|
67
|
+
from required to optional peer dependencies (`peerDependenciesMeta`, matching `@jini-ai/admin`'s
|
|
68
|
+
existing `./core`/`./browser` split) so `./core` stays importable without installing React. The
|
|
69
|
+
no-DOM guard `ui-core`'s own `vitest.config.ts` provided by never configuring a `jsdom` environment
|
|
70
|
+
is now enforced by `environmentMatchGlobs` over the (unchanged) centralized `src/__tests__/`
|
|
71
|
+
subtree that used to be `ui-core`'s whole test suite, so a DOM-dependent test landing there still
|
|
72
|
+
fails loudly instead of silently inheriting this package's `jsdom` default.
|
|
73
|
+
|
|
74
|
+
**`@jini-ai/ui-core` is retired, not versioned forward.** `packages/ui-core` is deleted from this
|
|
75
|
+
workspace; nothing else in it depended on the package name directly (only on `@jini-ai/ui`, which
|
|
76
|
+
already re-exported everything ui-core had). It had no confirmed external consumers, so a
|
|
77
|
+
deprecation-stub package was judged not worth the ongoing maintenance of keeping a zombie package
|
|
78
|
+
alive and published indefinitely for a name nothing currently needs. It was still published
|
|
79
|
+
(`0.1.2`, `publishConfig.access: public`), so it is not silently orphaned: whoever runs the next
|
|
80
|
+
release should follow up with `npm deprecate @jini-ai/ui-core "Merged into @jini-ai/ui; import from
|
|
81
|
+
'@jini-ai/ui/core' instead."` against the npm registry.
|
|
82
|
+
|
|
83
|
+
- 82ed2d3: Remove private fetch-query shims and point deprecated public type re-exports directly at core. Memory wired hooks require MemoryPortsProvider; deprecated REST/demo singletons remain explicit compatibility bindings pending a breaking-release removal.
|
|
84
|
+
- ea8d883: Remove obsolete fetch-query build shims and replace prose checks with runtime and type contract coverage.
|
|
85
|
+
- Updated dependencies [22f0619]
|
|
86
|
+
- Updated dependencies [82ed2d3]
|
|
87
|
+
- Updated dependencies [5a3de86]
|
|
88
|
+
- @jini-ai/core@0.6.10
|
|
89
|
+
|
|
90
|
+
## 0.5.6 — 2026-10-22
|
|
91
|
+
|
|
92
|
+
- 2026-10-22: MCP-UI question cards follow dark hosts, optional useCachedLoader fetch, trust options, html-editor fallbacks removed, coverage.
|
|
93
|
+
|
|
3
94
|
## 0.5.5 — 2026-10-16
|
|
4
95
|
|
|
5
96
|
- `admin-widgets` Select paints group headings and per-option badges (dc770a41) and is pane-aware; image fields name the file (bc1dbf0d).
|
|
@@ -77,7 +168,6 @@
|
|
|
77
168
|
- Adopt shared kernel contracts and preserve the module rationale in neutral documentation.
|
|
78
169
|
- BREAKING: replace package-local clock contracts with core Clock.nowMs().
|
|
79
170
|
|
|
80
|
-
|
|
81
171
|
### UI parity fixes
|
|
82
172
|
|
|
83
173
|
- Keep replacement writes successful when an older read rejects, including their freshness timestamp.
|
|
@@ -118,7 +208,6 @@
|
|
|
118
208
|
resolution hints move to the second object, including the renderer matching port.
|
|
119
209
|
- Canvas chrome attributes change to `data-jini-*`; hosts selecting the old attributes must update.
|
|
120
210
|
|
|
121
|
-
|
|
122
211
|
- Add generic admin widgets with opt-in `@jini-ai/ui/admin-widgets.css`, using the existing
|
|
123
212
|
`--jini-*` tokens with standalone fallbacks. `TabBar` joins the existing `tab-strip` feature
|
|
124
213
|
and shares its tablist shell; existing `TabStrip` exports and behavior remain available.
|
|
@@ -6,50 +6,52 @@ const safeValue = (value) => typeof value === 'string' && value.trim().length >
|
|
|
6
6
|
const component = '(?:[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:%|deg|rad|grad|turn)?|none)';
|
|
7
7
|
const components = new RegExp(`^(?:rgb|rgba|hsl|hsla|oklch|oklab|lab|lch)\\(\\s*${component}(?:\\s*,\\s*|\\s+)${component}(?:\\s*,\\s*|\\s+)${component}(?:(?:\\s*[,/]\\s*)${component})?\\s*\\)$`, 'i');
|
|
8
8
|
const colorValue = (value) => safeValue(value)
|
|
9
|
-
&& (/^#[\da-f]{3}(?:[\da-f]
|
|
9
|
+
&& (/^#[\da-f]{3}(?:[\da-f]|[\da-f]{3}|[\da-f]{5})?$/i.test(value)
|
|
10
10
|
|| components.test(value)
|
|
11
11
|
|| /^(?:transparent|black|white|red|green|blue|gray|grey)$/i.test(value));
|
|
12
|
+
const fontStacksValid = ({ fonts }) => record(fonts) && safeValue(fonts.body) && safeValue(fonts.heading) && (fonts.mono === undefined || safeValue(fonts.mono));
|
|
13
|
+
const stylesheetUrlValid = ({ url }) => {
|
|
14
|
+
if (typeof url !== 'string' || url.length > 4096 || /[\x00-\x20<>]/.test(url))
|
|
15
|
+
return false;
|
|
16
|
+
try {
|
|
17
|
+
return new URL(url, 'https://font-base.invalid').protocol === 'https:';
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const fontLoadValid = ({ load }) => load === undefined || (Array.isArray(load) && load.length <= 16 && load.every((url) => stylesheetUrlValid({ url })));
|
|
24
|
+
function fontErrors({ fonts }) {
|
|
25
|
+
const errors = [];
|
|
26
|
+
if (!fontStacksValid({ fonts }))
|
|
27
|
+
errors.push('fonts must provide body and heading font stacks');
|
|
28
|
+
if (record(fonts) && !fontLoadValid({ load: fonts.load }))
|
|
29
|
+
errors.push('fonts.load must contain relative or HTTPS stylesheet URLs');
|
|
30
|
+
return errors;
|
|
31
|
+
}
|
|
32
|
+
function paletteErrors({ scheme, colors }) {
|
|
33
|
+
if (!record(colors))
|
|
34
|
+
return [`${scheme} must be a complete palette`];
|
|
35
|
+
const known = adminThemeColorKeys;
|
|
36
|
+
const invalid = adminThemeColorKeys.filter((key) => !Object.hasOwn(colors, key) || !colorValue(colors[key]))
|
|
37
|
+
.map((key) => `${scheme}.${key} must be a concrete CSS color`);
|
|
38
|
+
const unknown = Object.keys(colors).filter((key) => !known.includes(key)).map((key) => `${scheme}.${key} is not a theme color`);
|
|
39
|
+
return [...invalid, ...unknown];
|
|
40
|
+
}
|
|
41
|
+
const radiusValid = ({ radius }) => radius === undefined || (typeof radius === 'string' && /^(?:0|\d+(?:\.\d+)?(?:px|rem|em))$/.test(radius));
|
|
42
|
+
const densityValid = ({ density }) => density === undefined || (typeof density === 'number' && Number.isFinite(density) && density >= 0.5 && density <= 2);
|
|
12
43
|
/** Validate serializable theme data before any DOM or font-loading effect. */
|
|
13
44
|
export function validateAdminTheme({ theme }) {
|
|
14
|
-
const errors = [];
|
|
15
45
|
if (!record(theme))
|
|
16
46
|
return { valid: false, errors: ['Theme must be an object'] };
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (typeof url !== 'string' || url.length > 4096 || /[\x00-\x20<>]/.test(url))
|
|
26
|
-
return false;
|
|
27
|
-
try {
|
|
28
|
-
return new URL(url, 'https://font-base.invalid').protocol === 'https:';
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
}))
|
|
34
|
-
errors.push('fonts.load must contain relative or HTTPS stylesheet URLs');
|
|
35
|
-
}
|
|
36
|
-
for (const scheme of ['light', 'dark']) {
|
|
37
|
-
const colors = theme[scheme];
|
|
38
|
-
if (!record(colors)) {
|
|
39
|
-
errors.push(`${scheme} must be a complete palette`);
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
for (const key of adminThemeColorKeys)
|
|
43
|
-
if (!Object.hasOwn(colors, key) || !colorValue(colors[key]))
|
|
44
|
-
errors.push(`${scheme}.${key} must be a concrete CSS color`);
|
|
45
|
-
for (const key of Object.keys(colors))
|
|
46
|
-
if (!adminThemeColorKeys.includes(key))
|
|
47
|
-
errors.push(`${scheme}.${key} is not a theme color`);
|
|
48
|
-
}
|
|
49
|
-
if (theme.radius !== undefined && (typeof theme.radius !== 'string' || !/^(?:0|\d+(?:\.\d+)?(?:px|rem|em))$/.test(theme.radius)))
|
|
50
|
-
errors.push('radius must be a nonnegative CSS length');
|
|
51
|
-
if (theme.density !== undefined && (typeof theme.density !== 'number' || !Number.isFinite(theme.density) || theme.density < 0.5 || theme.density > 2))
|
|
52
|
-
errors.push('density must be between 0.5 and 2');
|
|
47
|
+
const errors = [
|
|
48
|
+
...(safeValue(theme.name) ? [] : ['name must be a nonempty safe string']),
|
|
49
|
+
...fontErrors({ fonts: theme.fonts }),
|
|
50
|
+
...paletteErrors({ scheme: 'light', colors: theme.light }),
|
|
51
|
+
...paletteErrors({ scheme: 'dark', colors: theme.dark }),
|
|
52
|
+
...(radiusValid({ radius: theme.radius }) ? [] : ['radius must be a nonnegative CSS length']),
|
|
53
|
+
...(densityValid({ density: theme.density }) ? [] : ['density must be between 0.5 and 2']),
|
|
54
|
+
];
|
|
53
55
|
return errors.length ? { valid: false, errors } : { valid: true, theme: theme };
|
|
54
56
|
}
|
|
55
57
|
//# sourceMappingURL=validation.js.map
|
|
@@ -11,6 +11,19 @@ const PROVIDER_ACTION_PROPS = new Map([
|
|
|
11
11
|
['shadcn.text-input', 'onValueChange'],
|
|
12
12
|
['shadcn.select', 'onValueChange'],
|
|
13
13
|
]);
|
|
14
|
+
function renderRegistryComponent({ component, registry, componentId, onAction }, _options = {}) {
|
|
15
|
+
const entry = registry.resolveById({ id: component.component });
|
|
16
|
+
if (!entry) {
|
|
17
|
+
return (_jsxs("span", { className: "a2ui-placeholder", "data-a2ui-status": "unrenderable-type", "data-a2ui-component-id": componentId, children: ["\u26A0 no renderer yet for component type \"", component.component, "\""] }));
|
|
18
|
+
}
|
|
19
|
+
const RegistryComponent = entry.Component;
|
|
20
|
+
// `onRowClick` belongs to `native.data-table`/`shadcn.data-table`, not a generic
|
|
21
|
+
// per-component-type feedback convention — each non-table provider needs an explicit
|
|
22
|
+
// callback contract, supplied by the built-in map or its registry entry, not a guess.
|
|
23
|
+
// Unannotated custom entries retain the old table callback for compatibility.
|
|
24
|
+
const actionProp = entry.actionProp ?? PROVIDER_ACTION_PROPS.get(entry.id) ?? 'onRowClick';
|
|
25
|
+
return _jsx(RegistryComponent, { ...component.props, [actionProp]: () => onAction(componentId) });
|
|
26
|
+
}
|
|
14
27
|
/**
|
|
15
28
|
* Recursively walks a surface's component map from `componentId` — same shape as
|
|
16
29
|
* `@jini-ai/chat/react`'s `A2uiSurfaceCard`'s `RenderComponent` (cycle guard via `ancestors`,
|
|
@@ -59,19 +72,8 @@ function RenderNode({ interpreter, surfaceId, registry, componentId, ancestors,
|
|
|
59
72
|
return (_jsx("div", { className: "a2ui-card", "data-a2ui-component-id": componentId, children: _jsx(RenderNode, { ...childProps, componentId: String(component.props.child) }) }));
|
|
60
73
|
case 'Button':
|
|
61
74
|
return (_jsx("button", { type: "button", className: `a2ui-button a2ui-button-${String(component.props.variant)}`, "data-a2ui-component-id": componentId, onClick: () => onAction(componentId), children: _jsx(RenderNode, { ...childProps, componentId: String(component.props.child) }) }));
|
|
62
|
-
default:
|
|
63
|
-
|
|
64
|
-
if (!entry) {
|
|
65
|
-
return (_jsxs("span", { className: "a2ui-placeholder", "data-a2ui-status": "unrenderable-type", "data-a2ui-component-id": componentId, children: ["\u26A0 no renderer yet for component type \"", component.component, "\""] }));
|
|
66
|
-
}
|
|
67
|
-
const RegistryComponent = entry.Component;
|
|
68
|
-
// `onRowClick` belongs to `native.data-table`/`shadcn.data-table`, not a generic
|
|
69
|
-
// per-component-type feedback convention — each non-table provider needs an explicit
|
|
70
|
-
// callback contract, supplied by the built-in map or its registry entry, not a guess.
|
|
71
|
-
// Unannotated custom entries retain the old table callback for compatibility.
|
|
72
|
-
const actionProp = entry.actionProp ?? PROVIDER_ACTION_PROPS.get(entry.id) ?? 'onRowClick';
|
|
73
|
-
return _jsx(RegistryComponent, { ...component.props, [actionProp]: () => onAction(componentId) });
|
|
74
|
-
}
|
|
75
|
+
default:
|
|
76
|
+
return renderRegistryComponent({ component, registry, componentId, onAction });
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
@@ -3,6 +3,65 @@ import { useMemo, useState } from 'react';
|
|
|
3
3
|
import { useT } from '../../../i18n/index.js';
|
|
4
4
|
import { deriveAboutUpdateControl, isAboutUpdateActionDisabled } from '../../rules.js';
|
|
5
5
|
import { useSilentUpdatesToggle } from '../hooks/useSilentUpdatesToggle.js';
|
|
6
|
+
/** Built-in (untranslated) copy for every label a host may override. */
|
|
7
|
+
const DEFAULT_LABELS = {
|
|
8
|
+
versionLabel: 'Version',
|
|
9
|
+
runtimeLabel: 'Runtime',
|
|
10
|
+
packagedLabel: 'Packaged',
|
|
11
|
+
developmentLabel: 'Development build',
|
|
12
|
+
channelLabel: 'Channel',
|
|
13
|
+
platformLabel: 'Platform',
|
|
14
|
+
archLabel: 'Architecture',
|
|
15
|
+
releaseLinkLabel: 'View releases',
|
|
16
|
+
actionFailedLabel: 'Something went wrong. Try again.',
|
|
17
|
+
versionUnavailableLabel: 'Version information is unavailable.',
|
|
18
|
+
silentUpdatesLabel: 'Install updates automatically',
|
|
19
|
+
silentUpdatesHint: 'Apply updates in the background without asking first.',
|
|
20
|
+
};
|
|
21
|
+
const LABEL_KEYS = Object.keys(DEFAULT_LABELS);
|
|
22
|
+
/** Each label is the host override when given, else the translated default. */
|
|
23
|
+
function resolveLabels({ t }, { labels }) {
|
|
24
|
+
const resolved = { ...DEFAULT_LABELS };
|
|
25
|
+
for (const key of LABEL_KEYS)
|
|
26
|
+
resolved[key] = labels?.[key] ?? t(DEFAULT_LABELS[key]);
|
|
27
|
+
return resolved;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The one thing that's genuinely render-local: whether an update action this
|
|
31
|
+
* tab itself kicked off is still in flight, and whether the last one failed.
|
|
32
|
+
*/
|
|
33
|
+
function useUpdateActionRunner({ onPerformUpdateAction, }) {
|
|
34
|
+
const [actionBusy, setActionBusy] = useState(false);
|
|
35
|
+
const [actionFailed, setActionFailed] = useState(false);
|
|
36
|
+
const run = (action) => {
|
|
37
|
+
setActionBusy(true);
|
|
38
|
+
setActionFailed(false);
|
|
39
|
+
void onPerformUpdateAction(action).then(() => setActionBusy(false), () => {
|
|
40
|
+
setActionBusy(false);
|
|
41
|
+
setActionFailed(true);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
return { actionBusy, actionFailed, run };
|
|
45
|
+
}
|
|
46
|
+
function UpdateActions({ control, primaryLabel, actionDisabled, onPrimaryAction, onOpenReleaseLink, releaseLinkLabel, }) {
|
|
47
|
+
// Origin styled 'download'/'install'/'quit' as primary and left 'check'
|
|
48
|
+
// plain; simplified to "any actionable state reads as primary, any inert
|
|
49
|
+
// one reads as ghost" — same visual intent, one fewer hardcoded branch,
|
|
50
|
+
// and it falls straight out of a field `deriveAboutUpdateControl` already
|
|
51
|
+
// computes rather than re-deriving OD's three-way action match.
|
|
52
|
+
const primaryButtonClassName = `jini-button${control.primaryAction ? ' jini-button-primary' : ' jini-button-ghost'}`;
|
|
53
|
+
return (_jsxs("div", { className: "jini-settings-about-actions", children: [primaryLabel ? (_jsx("button", { type: "button", className: primaryButtonClassName, disabled: actionDisabled, onClick: onPrimaryAction, "data-testid": "about-update-action", children: primaryLabel })) : null, control.showReleaseLink ? (_jsx("button", { type: "button", className: "jini-button jini-button-ghost", onClick: onOpenReleaseLink, "data-testid": "about-release-link", children: releaseLinkLabel })) : null] }));
|
|
54
|
+
}
|
|
55
|
+
/** A `<dt>/<dd>` row rendered only when the host supplied a value for it. */
|
|
56
|
+
function OptionalFactRow({ label, value }) {
|
|
57
|
+
return value ? (_jsxs("div", { children: [_jsx("dt", { children: label }), _jsx("dd", { children: value })] })) : null;
|
|
58
|
+
}
|
|
59
|
+
function VersionDetails({ appVersionInfo, labels, statusTone, statusText, actions, actionFailed }) {
|
|
60
|
+
return (_jsxs("dl", { className: "jini-settings-about-list", children: [_jsxs("div", { className: "jini-settings-about-version-row", children: [_jsxs("div", { className: "jini-settings-about-version-copy", children: [_jsx("dt", { children: labels.versionLabel }), _jsx("span", { className: "jini-settings-about-version-num", children: appVersionInfo.version }), _jsx("dd", { "aria-live": "polite", className: `jini-settings-about-status jini-settings-about-status--${statusTone}`, children: statusText })] }), actions] }), actionFailed ? (_jsx("p", { className: "jini-hint jini-settings-about-error", role: "status", children: labels.actionFailedLabel })) : null, _jsxs("div", { children: [_jsx("dt", { children: labels.runtimeLabel }), _jsx("dd", { children: appVersionInfo.packaged === false ? labels.developmentLabel : labels.packagedLabel })] }), _jsx(OptionalFactRow, { label: labels.channelLabel, value: appVersionInfo.channel }), _jsx(OptionalFactRow, { label: labels.platformLabel, value: appVersionInfo.platform }), _jsx(OptionalFactRow, { label: labels.archLabel, value: appVersionInfo.arch })] }));
|
|
61
|
+
}
|
|
62
|
+
function SilentUpdatesToggle({ silentUpdates, labels, }) {
|
|
63
|
+
return (_jsx("div", { className: "jini-settings-subsection jini-settings-about-silent-updates", children: _jsxs("label", { className: "jini-settings-about-toggle", children: [_jsx("input", { type: "checkbox", checked: silentUpdates.allowSilentUpdates, disabled: silentUpdates.busy, onChange: (event) => silentUpdates.toggle(event.currentTarget.checked), "data-testid": "about-silent-updates-toggle" }), _jsxs("span", { className: "jini-settings-about-toggle-copy", children: [_jsx("span", { children: labels.silentUpdatesLabel }), _jsx("span", { className: "jini-hint", children: labels.silentUpdatesHint })] })] }) }));
|
|
64
|
+
}
|
|
6
65
|
/**
|
|
7
66
|
* App version + auto-update panel, plus the "allow silent updates"
|
|
8
67
|
* preference. Origin: the `activeSection === 'about'` block in
|
|
@@ -25,46 +84,17 @@ import { useSilentUpdatesToggle } from '../hooks/useSilentUpdatesToggle.js';
|
|
|
25
84
|
*/
|
|
26
85
|
export function AboutTab({ appVersionInfo, updaterModel, onPerformUpdateAction, onOpenReleaseLink, allowSilentUpdates = false, onSilentUpdatePreferenceChange, labels, }) {
|
|
27
86
|
const t = useT();
|
|
28
|
-
const
|
|
29
|
-
const [actionFailed, setActionFailed] = useState(false);
|
|
87
|
+
const { actionBusy, actionFailed, run } = useUpdateActionRunner({ onPerformUpdateAction });
|
|
30
88
|
const silentUpdates = useSilentUpdatesToggle({ allowSilentUpdates, onSilentUpdatePreferenceChange });
|
|
31
|
-
const control = useMemo(() => deriveAboutUpdateControl(updaterModel, appVersionInfo
|
|
89
|
+
const control = useMemo(() => deriveAboutUpdateControl(updaterModel, appVersionInfo), [updaterModel, appVersionInfo]);
|
|
32
90
|
const actionDisabled = isAboutUpdateActionDisabled(control, updaterModel, actionBusy);
|
|
33
|
-
const
|
|
34
|
-
const runtimeLabel = labels?.runtimeLabel ?? t('Runtime');
|
|
35
|
-
const packagedLabel = labels?.packagedLabel ?? t('Packaged');
|
|
36
|
-
const developmentLabel = labels?.developmentLabel ?? t('Development build');
|
|
37
|
-
const channelLabel = labels?.channelLabel ?? t('Channel');
|
|
38
|
-
const platformLabel = labels?.platformLabel ?? t('Platform');
|
|
39
|
-
const archLabel = labels?.archLabel ?? t('Architecture');
|
|
40
|
-
const releaseLinkLabel = labels?.releaseLinkLabel ?? t('View releases');
|
|
41
|
-
const actionFailedLabel = labels?.actionFailedLabel ?? t('Something went wrong. Try again.');
|
|
42
|
-
const versionUnavailableLabel = labels?.versionUnavailableLabel ?? t('Version information is unavailable.');
|
|
43
|
-
const silentUpdatesLabel = labels?.silentUpdatesLabel ?? t('Install updates automatically');
|
|
44
|
-
const silentUpdatesHint = labels?.silentUpdatesHint ?? t('Apply updates in the background without asking first.');
|
|
45
|
-
const statusText = t(control.statusKey, control.statusVars);
|
|
46
|
-
const primaryLabel = control.primaryLabelKey ? t(control.primaryLabelKey) : null;
|
|
47
|
-
// Origin styled 'download'/'install'/'quit' as primary and left 'check'
|
|
48
|
-
// plain; simplified to "any actionable state reads as primary, any inert
|
|
49
|
-
// one reads as ghost" — same visual intent, one fewer hardcoded branch,
|
|
50
|
-
// and it falls straight out of a field `deriveAboutUpdateControl` already
|
|
51
|
-
// computes rather than re-deriving OD's three-way action match.
|
|
52
|
-
const primaryButtonClassName = `jini-button${control.primaryAction ? ' jini-button-primary' : ' jini-button-ghost'}`;
|
|
91
|
+
const resolvedLabels = resolveLabels({ t }, { labels });
|
|
53
92
|
// `handlePrimaryAction` only exists when there is an action to run — it is
|
|
54
93
|
// `undefined` in every state that renders the button disabled-and-inert
|
|
55
94
|
// (e.g. "downloading"), so there is no dead "disabled but somehow clicked"
|
|
56
95
|
// branch to guard against inside the handler itself.
|
|
57
96
|
const { primaryAction } = control;
|
|
58
|
-
const handlePrimaryAction = primaryAction == null
|
|
59
|
-
|
|
60
|
-
: () => {
|
|
61
|
-
setActionBusy(true);
|
|
62
|
-
setActionFailed(false);
|
|
63
|
-
void onPerformUpdateAction(primaryAction).then(() => setActionBusy(false), () => {
|
|
64
|
-
setActionBusy(false);
|
|
65
|
-
setActionFailed(true);
|
|
66
|
-
});
|
|
67
|
-
};
|
|
68
|
-
return (_jsxs("section", { className: "jini-settings-section jini-settings-about", children: [appVersionInfo ? (_jsxs("dl", { className: "jini-settings-about-list", children: [_jsxs("div", { className: "jini-settings-about-version-row", children: [_jsxs("div", { className: "jini-settings-about-version-copy", children: [_jsx("dt", { children: versionLabel }), _jsx("span", { className: "jini-settings-about-version-num", children: appVersionInfo.version }), _jsx("dd", { "aria-live": "polite", className: `jini-settings-about-status jini-settings-about-status--${control.statusTone}`, children: statusText })] }), _jsxs("div", { className: "jini-settings-about-actions", children: [primaryLabel ? (_jsx("button", { type: "button", className: primaryButtonClassName, disabled: actionDisabled, onClick: handlePrimaryAction, "data-testid": "about-update-action", children: primaryLabel })) : null, control.showReleaseLink ? (_jsx("button", { type: "button", className: "jini-button jini-button-ghost", onClick: onOpenReleaseLink, "data-testid": "about-release-link", children: releaseLinkLabel })) : null] })] }), actionFailed ? (_jsx("p", { className: "jini-hint jini-settings-about-error", role: "status", children: actionFailedLabel })) : null, _jsxs("div", { children: [_jsx("dt", { children: runtimeLabel }), _jsx("dd", { children: appVersionInfo.packaged === false ? developmentLabel : packagedLabel })] }), appVersionInfo.channel ? (_jsxs("div", { children: [_jsx("dt", { children: channelLabel }), _jsx("dd", { children: appVersionInfo.channel })] })) : null, appVersionInfo.platform ? (_jsxs("div", { children: [_jsx("dt", { children: platformLabel }), _jsx("dd", { children: appVersionInfo.platform })] })) : null, appVersionInfo.arch ? (_jsxs("div", { children: [_jsx("dt", { children: archLabel }), _jsx("dd", { children: appVersionInfo.arch })] })) : null] })) : (_jsx("div", { className: "jini-empty-card", children: versionUnavailableLabel })), onSilentUpdatePreferenceChange ? (_jsx("div", { className: "jini-settings-subsection jini-settings-about-silent-updates", children: _jsxs("label", { className: "jini-settings-about-toggle", children: [_jsx("input", { type: "checkbox", checked: silentUpdates.allowSilentUpdates, disabled: silentUpdates.busy, onChange: (event) => silentUpdates.toggle(event.currentTarget.checked), "data-testid": "about-silent-updates-toggle" }), _jsxs("span", { className: "jini-settings-about-toggle-copy", children: [_jsx("span", { children: silentUpdatesLabel }), _jsx("span", { className: "jini-hint", children: silentUpdatesHint })] })] }) })) : null] }));
|
|
97
|
+
const handlePrimaryAction = primaryAction == null ? undefined : () => run(primaryAction);
|
|
98
|
+
return (_jsxs("section", { className: "jini-settings-section jini-settings-about", children: [appVersionInfo ? (_jsx(VersionDetails, { appVersionInfo: appVersionInfo, labels: resolvedLabels, statusTone: control.statusTone, statusText: t(control.statusKey, control.statusVars), actionFailed: actionFailed, actions: _jsx(UpdateActions, { control: control, primaryLabel: control.primaryLabelKey ? t(control.primaryLabelKey) : null, actionDisabled: actionDisabled, onPrimaryAction: handlePrimaryAction, onOpenReleaseLink: onOpenReleaseLink, releaseLinkLabel: resolvedLabels.releaseLinkLabel }) })) : (_jsx("div", { className: "jini-empty-card", children: resolvedLabels.versionUnavailableLabel })), onSilentUpdatePreferenceChange ? _jsx(SilentUpdatesToggle, { silentUpdates: silentUpdates, labels: resolvedLabels }) : null] }));
|
|
69
99
|
}
|
|
70
100
|
//# sourceMappingURL=AboutTab.js.map
|
|
@@ -46,7 +46,7 @@ export declare const ABOUT_UPDATE_KEYS: {
|
|
|
46
46
|
* build — one shared "unsupported" outcome, since the operator can do
|
|
47
47
|
* nothing about any of them from this panel.
|
|
48
48
|
*
|
|
49
|
-
* After that it is a
|
|
49
|
+
* After that it is a lookup of the reported state in `STATE_DERIVERS`. Two subtleties worth
|
|
50
50
|
* keeping when reading it:
|
|
51
51
|
*
|
|
52
52
|
* - `primaryLabelKey` can be set while `primaryAction` is `null`. That is the
|
|
@@ -56,7 +56,7 @@ export declare const ABOUT_UPDATE_KEYS: {
|
|
|
56
56
|
* about to disappear (installing, or quitting to let an installer run).
|
|
57
57
|
* Offering a navigation there invites a click that cannot complete.
|
|
58
58
|
*
|
|
59
|
-
* @complexity O(1) — a fixed
|
|
59
|
+
* @complexity O(1) — a fixed-size map lookup, no iteration.
|
|
60
60
|
*/
|
|
61
61
|
export declare function deriveAboutUpdateControl(model: UpdaterModel, appVersionInfo: AppVersionInfo | null): AboutUpdateControl;
|
|
62
62
|
/**
|