@jini-ai/admin 0.3.10 → 0.4.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 +58 -0
- package/README.md +71 -37
- package/dist/agent-plugins/adapters/http.d.ts +7 -0
- package/dist/agent-plugins/adapters/http.js +15 -0
- package/dist/agent-plugins/adapters/memory.d.ts +8 -0
- package/dist/agent-plugins/adapters/memory.js +25 -0
- package/dist/agent-plugins/agent-plugins.module.d.ts +51 -0
- package/dist/agent-plugins/agent-plugins.module.js +6 -0
- package/dist/agent-plugins/conformance/agent-plugins-api.conformance.d.ts +12 -0
- package/dist/agent-plugins/conformance/agent-plugins-api.conformance.js +47 -0
- package/dist/agent-plugins/controllers/agent-plugin-files.controller.d.ts +20 -0
- package/dist/agent-plugins/controllers/agent-plugin-files.controller.js +43 -0
- package/dist/agent-plugins/controllers/agent-plugins.controller.d.ts +25 -0
- package/dist/agent-plugins/controllers/agent-plugins.controller.js +91 -0
- package/dist/agent-plugins/index.d.ts +9 -0
- package/dist/agent-plugins/index.js +9 -0
- package/dist/agent-plugins/messages.en.d.ts +23 -0
- package/dist/agent-plugins/messages.en.js +14 -0
- package/dist/agent-plugins/models.d.ts +57 -0
- package/dist/agent-plugins/models.js +2 -0
- package/dist/agent-plugins/package-file-tree.d.ts +111 -0
- package/dist/agent-plugins/package-file-tree.js +188 -0
- package/dist/agent-plugins/ports.d.ts +18 -0
- package/dist/agent-plugins/ports.js +3 -0
- package/dist/agent-plugins/react/components/AgentPluginFileContent.d.ts +5 -0
- package/dist/agent-plugins/react/components/AgentPluginFileContent.js +9 -0
- package/dist/agent-plugins/react/components/AgentPluginFileTree.d.ts +9 -0
- package/dist/agent-plugins/react/components/AgentPluginFileTree.js +7 -0
- package/dist/agent-plugins/react/components/AgentPluginInspector.d.ts +3 -0
- package/dist/agent-plugins/react/components/AgentPluginInspector.js +11 -0
- package/dist/agent-plugins/react/components/AgentPluginListPanel.d.ts +6 -0
- package/dist/agent-plugins/react/components/AgentPluginListPanel.js +10 -0
- package/dist/agent-plugins/react/components/AgentPluginRow.d.ts +5 -0
- package/dist/agent-plugins/react/components/AgentPluginRow.js +8 -0
- package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.d.ts +90 -0
- package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.js +74 -0
- package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.d.ts +67 -0
- package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.js +50 -0
- package/dist/agent-plugins/react/hooks/AgentPluginRow.hooks.d.ts +55 -0
- package/dist/agent-plugins/react/hooks/AgentPluginRow.hooks.js +6 -0
- package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.d.ts +64 -0
- package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.js +39 -0
- package/dist/agent-plugins/react/hooks/AgentPluginsPorts.hooks.d.ts +7 -0
- package/dist/agent-plugins/react/hooks/AgentPluginsPorts.hooks.js +10 -0
- package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.d.ts +6 -0
- package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.js +3 -0
- package/dist/agent-plugins/react/index.d.ts +245 -0
- package/dist/agent-plugins/react/index.js +13 -0
- package/dist/agent-plugins/react/pages/AgentPluginsPage.d.ts +4 -0
- package/dist/agent-plugins/react/pages/AgentPluginsPage.js +12 -0
- package/dist/agent-plugins/react/tabs/DownloadedTab.d.ts +4 -0
- package/dist/agent-plugins/react/tabs/DownloadedTab.js +5 -0
- package/dist/agent-plugins/react/tabs/InstalledTab.d.ts +4 -0
- package/dist/agent-plugins/react/tabs/InstalledTab.js +5 -0
- package/dist/agent-plugins/react/tabs/MarketplaceTab.d.ts +4 -0
- package/dist/agent-plugins/react/tabs/MarketplaceTab.js +10 -0
- package/dist/agent-plugins/rules.d.ts +33 -0
- package/dist/agent-plugins/rules.js +51 -0
- package/dist/browser/index.d.ts +1 -0
- package/dist/browser/index.js +1 -0
- package/dist/browser/navigation.d.ts +19 -4
- package/dist/browser/navigation.js +8 -8
- package/dist/browser/shell-navigation.d.ts +12 -0
- package/dist/browser/shell-navigation.js +16 -0
- package/dist/contracts/credential-management.d.ts +8 -0
- package/dist/contracts/credential-management.js +3 -0
- package/dist/contracts/media-picker.d.ts +17 -0
- package/dist/contracts/media-picker.js +5 -0
- package/dist/contracts/playground-render-target.d.ts +18 -0
- package/dist/contracts/playground-render-target.js +3 -0
- package/dist/core/entities/rules.d.ts +138 -0
- package/dist/core/entities/rules.js +344 -0
- package/dist/core/gated/types.d.ts +8 -4
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +1 -0
- package/dist/core/manifest/rules.d.ts +24 -6
- package/dist/core/manifest/rules.js +12 -11
- package/dist/core/module/controller-store.d.ts +22 -0
- package/dist/core/module/controller-store.js +32 -0
- package/dist/core/module/create-admin.d.ts +41 -0
- package/dist/core/module/create-admin.js +187 -0
- package/dist/core/module/define-admin-module.d.ts +4 -0
- package/dist/core/module/define-admin-module.js +5 -0
- package/dist/core/module/index.d.ts +7 -0
- package/dist/core/module/index.js +4 -0
- package/dist/core/module/token.d.ts +19 -0
- package/dist/core/module/token.js +4 -0
- package/dist/core/module/types.d.ts +79 -0
- package/dist/core/module/types.js +2 -0
- package/dist/core/permissions/rules.d.ts +4 -1
- package/dist/core/permissions/rules.js +1 -1
- package/dist/core/ports/analytics.d.ts +1 -1
- package/dist/core/ports/auth.d.ts +2 -2
- package/dist/core/ports/comments.d.ts +9 -6
- package/dist/core/ports/database.d.ts +13 -10
- package/dist/core/ports/entities.d.ts +302 -0
- package/dist/core/ports/entities.js +47 -0
- package/dist/core/ports/forms.d.ts +19 -7
- package/dist/core/ports/identity.d.ts +42 -17
- package/dist/core/ports/index.d.ts +2 -0
- package/dist/core/ports/integrations.d.ts +9 -4
- package/dist/core/ports/media.d.ts +16 -7
- package/dist/core/ports/members.d.ts +7 -3
- package/dist/core/ports/menus.d.ts +43 -0
- package/dist/core/ports/menus.js +43 -0
- package/dist/core/ports/plugins.d.ts +3 -2
- package/dist/core/ports/recovery.d.ts +10 -6
- package/dist/core/ports/redirects.d.ts +17 -7
- package/dist/core/ports/seo.d.ts +12 -6
- package/dist/core/ports/shell.d.ts +41 -0
- package/dist/core/ports/shell.js +2 -0
- package/dist/core/ports/workspace.d.ts +3 -3
- package/dist/core/routing/rules.d.ts +17 -4
- package/dist/core/routing/rules.js +4 -4
- package/dist/core/transport/errors.d.ts +13 -4
- package/dist/core/transport/errors.js +4 -4
- package/dist/core/transport/http.d.ts +26 -16
- package/dist/core/transport/http.js +59 -21
- package/dist/core/transport/types.d.ts +26 -14
- package/dist/core/transport/types.js +9 -7
- package/dist/media/adapters/http.d.ts +27 -0
- package/dist/media/adapters/http.js +44 -0
- package/dist/media/adapters/memory.d.ts +11 -0
- package/dist/media/adapters/memory.js +139 -0
- package/dist/media/conformance/media-api.conformance.d.ts +7 -0
- package/dist/media/conformance/media-api.conformance.js +69 -0
- package/dist/media/controllers/edit-media.controller.d.ts +24 -0
- package/dist/media/controllers/edit-media.controller.js +69 -0
- package/dist/media/controllers/library.controller.d.ts +47 -0
- package/dist/media/controllers/library.controller.js +173 -0
- package/dist/media/controllers/providers.controller.d.ts +30 -0
- package/dist/media/controllers/providers.controller.js +76 -0
- package/dist/media/html-attributes.d.ts +82 -0
- package/dist/media/html-attributes.js +204 -0
- package/dist/media/index.d.ts +12 -0
- package/dist/media/index.js +9 -0
- package/dist/media/media.module.d.ts +83 -0
- package/dist/media/media.module.js +43 -0
- package/dist/media/messages.en.d.ts +24 -0
- package/dist/media/messages.en.js +24 -0
- package/dist/media/models.d.ts +72 -0
- package/dist/media/models.js +2 -0
- package/dist/media/ports.d.ts +75 -0
- package/dist/media/ports.js +7 -0
- package/dist/media/react/components/EditMediaPanel.d.ts +3 -0
- package/dist/media/react/components/EditMediaPanel.js +10 -0
- package/dist/media/react/components/MediaCard.d.ts +5 -0
- package/dist/media/react/components/MediaCard.js +17 -0
- package/dist/media/react/components/MediaDialog.d.ts +3 -0
- package/dist/media/react/components/MediaDialog.js +8 -0
- package/dist/media/react/components/MediaGrid.d.ts +4 -0
- package/dist/media/react/components/MediaGrid.js +8 -0
- package/dist/media/react/components/MediaIcons.d.ts +14 -0
- package/dist/media/react/components/MediaIcons.js +39 -0
- package/dist/media/react/components/MediaLightbox.d.ts +5 -0
- package/dist/media/react/components/MediaLightbox.js +12 -0
- package/dist/media/react/components/MediaPicker.d.ts +3 -0
- package/dist/media/react/components/MediaPicker.js +10 -0
- package/dist/media/react/components/MediaPurgeDialog.d.ts +4 -0
- package/dist/media/react/components/MediaPurgeDialog.js +9 -0
- package/dist/media/react/components/UploadButton.d.ts +3 -0
- package/dist/media/react/components/UploadButton.js +8 -0
- package/dist/media/react/hooks/EditMediaPanel.hooks.d.ts +84 -0
- package/dist/media/react/hooks/EditMediaPanel.hooks.js +105 -0
- package/dist/media/react/hooks/LibraryTab.hooks.d.ts +103 -0
- package/dist/media/react/hooks/LibraryTab.hooks.js +164 -0
- package/dist/media/react/hooks/MediaCard.hooks.d.ts +79 -0
- package/dist/media/react/hooks/MediaCard.hooks.js +63 -0
- package/dist/media/react/hooks/MediaDialog.hooks.d.ts +10 -0
- package/dist/media/react/hooks/MediaDialog.hooks.js +20 -0
- package/dist/media/react/hooks/MediaGrid.hooks.d.ts +28 -0
- package/dist/media/react/hooks/MediaGrid.hooks.js +6 -0
- package/dist/media/react/hooks/MediaLightbox.hooks.d.ts +27 -0
- package/dist/media/react/hooks/MediaLightbox.hooks.js +64 -0
- package/dist/media/react/hooks/MediaPage.hooks.d.ts +68 -0
- package/dist/media/react/hooks/MediaPage.hooks.js +68 -0
- package/dist/media/react/hooks/MediaPicker.hooks.d.ts +26 -0
- package/dist/media/react/hooks/MediaPicker.hooks.js +25 -0
- package/dist/media/react/hooks/MediaPorts.hooks.d.ts +9 -0
- package/dist/media/react/hooks/MediaPorts.hooks.js +10 -0
- package/dist/media/react/hooks/MediaPurgeDialog.hooks.d.ts +22 -0
- package/dist/media/react/hooks/MediaPurgeDialog.hooks.js +6 -0
- package/dist/media/react/hooks/ProvidersTab.hooks.d.ts +55 -0
- package/dist/media/react/hooks/ProvidersTab.hooks.js +124 -0
- package/dist/media/react/hooks/UploadButton.hooks.d.ts +48 -0
- package/dist/media/react/hooks/UploadButton.hooks.js +118 -0
- package/dist/media/react/index.d.ts +373 -0
- package/dist/media/react/index.js +73 -0
- package/dist/media/react/pages/MediaPage.d.ts +4 -0
- package/dist/media/react/pages/MediaPage.js +9 -0
- package/dist/media/react/tabs/LibraryTab.d.ts +4 -0
- package/dist/media/react/tabs/LibraryTab.js +14 -0
- package/dist/media/react/tabs/ProvidersTab.d.ts +4 -0
- package/dist/media/react/tabs/ProvidersTab.js +10 -0
- package/dist/media/rules.d.ts +80 -0
- package/dist/media/rules.js +127 -0
- package/dist/media/styles.d.ts +4 -0
- package/dist/media/styles.js +5 -0
- package/dist/playground/adapters/http.d.ts +8 -0
- package/dist/playground/adapters/http.js +4 -0
- package/dist/playground/adapters/memory.d.ts +10 -0
- package/dist/playground/adapters/memory.js +30 -0
- package/dist/playground/conformance/playground-api.conformance.d.ts +6 -0
- package/dist/playground/conformance/playground-api.conformance.js +37 -0
- package/dist/playground/controllers/playground.controller.d.ts +16 -0
- package/dist/playground/controllers/playground.controller.js +21 -0
- package/dist/playground/index.d.ts +7 -0
- package/dist/playground/index.js +5 -0
- package/dist/playground/messages.en.d.ts +9 -0
- package/dist/playground/messages.en.js +2 -0
- package/dist/playground/models.d.ts +4 -0
- package/dist/playground/models.js +2 -0
- package/dist/playground/playground.module.d.ts +31 -0
- package/dist/playground/playground.module.js +5 -0
- package/dist/playground/ports.d.ts +5 -0
- package/dist/playground/ports.js +2 -0
- package/dist/playground/react/components/Canvas.d.ts +3 -0
- package/dist/playground/react/components/Canvas.js +9 -0
- package/dist/playground/react/hooks/Canvas.hooks.d.ts +7 -0
- package/dist/playground/react/hooks/Canvas.hooks.js +18 -0
- package/dist/playground/react/hooks/PlaygroundPage.hooks.d.ts +8 -0
- package/dist/playground/react/hooks/PlaygroundPage.hooks.js +2 -0
- package/dist/playground/react/hooks/PlaygroundPorts.hooks.d.ts +4 -0
- package/dist/playground/react/hooks/PlaygroundPorts.hooks.js +6 -0
- package/dist/playground/react/index.d.ts +136 -0
- package/dist/playground/react/index.js +10 -0
- package/dist/playground/react/pages/PlaygroundPage.d.ts +4 -0
- package/dist/playground/react/pages/PlaygroundPage.js +11 -0
- package/dist/playground/react/tabs/CanvasTab.d.ts +4 -0
- package/dist/playground/react/tabs/CanvasTab.js +5 -0
- package/dist/playground/rules.d.ts +4 -0
- package/dist/playground/rules.js +2 -0
- package/dist/react/OverlayHost.d.ts +3 -0
- package/dist/react/OverlayHost.hooks.d.ts +9 -0
- package/dist/react/OverlayHost.hooks.js +9 -0
- package/dist/react/OverlayHost.js +7 -0
- package/dist/react/bind-react.d.ts +46 -0
- package/dist/react/bind-react.js +28 -0
- package/dist/react/components/ConfirmButton/ConfirmButton.hooks.d.ts +7 -1
- package/dist/react/components/ConfirmButton/ConfirmButton.hooks.js +2 -2
- package/dist/react/components/ConfirmButton/ConfirmButton.js +1 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +17 -3
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +3 -3
- package/dist/react/components/ConfirmDialog/ConfirmDialog.js +5 -5
- package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.d.ts +6 -2
- package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.js +7 -8
- package/dist/react/components/RowMenu/RowMenu.d.ts +5 -1
- package/dist/react/components/RowMenu/RowMenu.hooks.d.ts +8 -2
- package/dist/react/components/RowMenu/RowMenu.hooks.js +4 -4
- package/dist/react/components/RowMenu/RowMenu.js +6 -6
- package/dist/react/components/Sidebar.d.ts +1 -1
- package/dist/react/components/Sidebar.js +103 -7
- package/dist/react/entities/EntityCell.d.ts +10 -0
- package/dist/react/entities/EntityCell.js +18 -0
- package/dist/react/entities/EntityDetail.d.ts +3 -0
- package/dist/react/entities/EntityDetail.js +21 -0
- package/dist/react/entities/EntityEdit.d.ts +13 -0
- package/dist/react/entities/EntityEdit.js +45 -0
- package/dist/react/entities/EntityField.d.ts +20 -0
- package/dist/react/entities/EntityField.js +31 -0
- package/dist/react/entities/EntityIndex.d.ts +3 -0
- package/dist/react/entities/EntityIndex.js +10 -0
- package/dist/react/entities/EntityList.d.ts +7 -0
- package/dist/react/entities/EntityList.js +52 -0
- package/dist/react/entities/contribution.d.ts +26 -0
- package/dist/react/entities/contribution.js +78 -0
- package/dist/react/entities/index.d.ts +10 -0
- package/dist/react/entities/index.js +7 -0
- package/dist/react/entities/rules.d.ts +179 -0
- package/dist/react/entities/rules.js +224 -0
- package/dist/react/entities/types.d.ts +45 -0
- package/dist/react/entities/types.js +5 -0
- package/dist/react/entities/use-entity-edit.d.ts +35 -0
- package/dist/react/entities/use-entity-edit.js +98 -0
- package/dist/react/entities/use-entity-read.d.ts +22 -0
- package/dist/react/entities/use-entity-read.js +27 -0
- package/dist/react/hooks/use-nav-sections.d.ts +12 -3
- package/dist/react/hooks/use-nav-sections.js +14 -14
- package/dist/react/hooks/use-sidebar-rail.d.ts +7 -1
- package/dist/react/hooks/use-sidebar-rail.js +11 -11
- package/dist/react/index.d.ts +3 -1
- package/dist/react/index.js +5 -2
- package/dist/react/kit/Kit.hooks.d.ts +13 -0
- package/dist/react/kit/Kit.hooks.js +10 -0
- package/dist/react/kit/Native.hooks.d.ts +38 -0
- package/dist/react/kit/Native.hooks.js +65 -0
- package/dist/react/kit/index.d.ts +12 -0
- package/dist/react/kit/index.js +21 -0
- package/dist/react/kit/native.d.ts +3 -0
- package/dist/react/kit/native.js +21 -0
- package/dist/react/kit/types.d.ts +40 -0
- package/dist/react/kit/types.js +2 -0
- package/dist/react/overlay.d.ts +36 -0
- package/dist/react/overlay.js +35 -0
- package/dist/react/overlays.d.ts +38 -0
- package/dist/react/overlays.js +46 -0
- package/dist/react/shell/AdminShell.d.ts +9 -0
- package/dist/react/shell/AdminShell.hooks.d.ts +15 -0
- package/dist/react/shell/AdminShell.hooks.js +27 -0
- package/dist/react/shell/AdminShell.js +46 -0
- package/dist/react/shell/index.d.ts +7 -0
- package/dist/react/shell/index.js +5 -0
- package/dist/react/shell/model.d.ts +25 -0
- package/dist/react/shell/model.js +29 -0
- package/dist/react/shell/theme-ports.d.ts +28 -0
- package/dist/react/shell/theme-ports.js +2 -0
- package/dist/react/shell/types.d.ts +99 -0
- package/dist/react/shell/types.js +2 -0
- package/dist/react/shell/use-admin-shell-session.d.ts +13 -0
- package/dist/react/shell/use-admin-shell-session.js +81 -0
- package/dist/react/shell/use-admin-theme.d.ts +16 -0
- package/dist/react/shell/use-admin-theme.js +57 -0
- package/dist/react/types.d.ts +6 -4
- package/dist/react/types.js +2 -2
- package/dist/react/use-controller.d.ts +16 -0
- package/dist/react/use-controller.js +18 -0
- package/dist/security/adapters/http.d.ts +16 -0
- package/dist/security/adapters/http.js +94 -0
- package/dist/security/adapters/memory.d.ts +15 -0
- package/dist/security/adapters/memory.js +60 -0
- package/dist/security/conformance/security-api.conformance.d.ts +10 -0
- package/dist/security/conformance/security-api.conformance.js +48 -0
- package/dist/security/controllers/access-tokens.controller.d.ts +44 -0
- package/dist/security/controllers/access-tokens.controller.js +112 -0
- package/dist/security/controllers/other-credentials.controller.d.ts +30 -0
- package/dist/security/controllers/other-credentials.controller.js +74 -0
- package/dist/security/controllers/root-key.controller.d.ts +35 -0
- package/dist/security/controllers/root-key.controller.js +90 -0
- package/dist/security/index.d.ts +9 -0
- package/dist/security/index.js +9 -0
- package/dist/security/messages.en.d.ts +12 -0
- package/dist/security/messages.en.js +2 -0
- package/dist/security/models.d.ts +112 -0
- package/dist/security/models.js +2 -0
- package/dist/security/ports.d.ts +58 -0
- package/dist/security/ports.js +5 -0
- package/dist/security/react/components/CredentialEditor.d.ts +3 -0
- package/dist/security/react/components/CredentialEditor.js +8 -0
- package/dist/security/react/hooks/AccessTokensTab.hooks.d.ts +94 -0
- package/dist/security/react/hooks/AccessTokensTab.hooks.js +36 -0
- package/dist/security/react/hooks/CredentialEditor.hooks.d.ts +49 -0
- package/dist/security/react/hooks/CredentialEditor.hooks.js +14 -0
- package/dist/security/react/hooks/RootKeyTab.hooks.d.ts +29 -0
- package/dist/security/react/hooks/RootKeyTab.hooks.js +19 -0
- package/dist/security/react/hooks/SecurityPage.hooks.d.ts +17 -0
- package/dist/security/react/hooks/SecurityPage.hooks.js +12 -0
- package/dist/security/react/hooks/SecurityPorts.hooks.d.ts +9 -0
- package/dist/security/react/hooks/SecurityPorts.hooks.js +6 -0
- package/dist/security/react/index.d.ts +215 -0
- package/dist/security/react/index.js +10 -0
- package/dist/security/react/pages/SecurityPage.d.ts +4 -0
- package/dist/security/react/pages/SecurityPage.js +10 -0
- package/dist/security/react/tabs/AccessTokensTab.d.ts +4 -0
- package/dist/security/react/tabs/AccessTokensTab.js +10 -0
- package/dist/security/react/tabs/RootKeyTab.d.ts +4 -0
- package/dist/security/react/tabs/RootKeyTab.js +9 -0
- package/dist/security/rules.d.ts +57 -0
- package/dist/security/rules.js +63 -0
- package/dist/security/security.module.d.ts +45 -0
- package/dist/security/security.module.js +5 -0
- package/dist/source-control/adapters/http.d.ts +6 -0
- package/dist/source-control/adapters/http.js +13 -0
- package/dist/source-control/adapters/memory.d.ts +9 -0
- package/dist/source-control/adapters/memory.js +35 -0
- package/dist/source-control/conformance/source-control-api.conformance.d.ts +10 -0
- package/dist/source-control/conformance/source-control-api.conformance.js +48 -0
- package/dist/source-control/controllers/source-control.controller.d.ts +26 -0
- package/dist/source-control/controllers/source-control.controller.js +70 -0
- package/dist/source-control/index.d.ts +8 -0
- package/dist/source-control/index.js +6 -0
- package/dist/source-control/messages.en.d.ts +11 -0
- package/dist/source-control/messages.en.js +2 -0
- package/dist/source-control/models.d.ts +70 -0
- package/dist/source-control/models.js +2 -0
- package/dist/source-control/ports.d.ts +23 -0
- package/dist/source-control/ports.js +3 -0
- package/dist/source-control/react/components/SourceControlCredentialFields.d.ts +5 -0
- package/dist/source-control/react/components/SourceControlCredentialFields.js +8 -0
- package/dist/source-control/react/components/SourceControlProviderRow.d.ts +5 -0
- package/dist/source-control/react/components/SourceControlProviderRow.js +7 -0
- package/dist/source-control/react/hooks/ProvidersTab.hooks.d.ts +45 -0
- package/dist/source-control/react/hooks/ProvidersTab.hooks.js +20 -0
- package/dist/source-control/react/hooks/SourceControlCredentialFields.hooks.d.ts +43 -0
- package/dist/source-control/react/hooks/SourceControlCredentialFields.hooks.js +9 -0
- package/dist/source-control/react/hooks/SourceControlPage.hooks.d.ts +17 -0
- package/dist/source-control/react/hooks/SourceControlPage.hooks.js +5 -0
- package/dist/source-control/react/hooks/SourceControlPorts.hooks.d.ts +9 -0
- package/dist/source-control/react/hooks/SourceControlPorts.hooks.js +6 -0
- package/dist/source-control/react/index.d.ts +156 -0
- package/dist/source-control/react/index.js +10 -0
- package/dist/source-control/react/pages/SourceControlPage.d.ts +4 -0
- package/dist/source-control/react/pages/SourceControlPage.js +11 -0
- package/dist/source-control/react/tabs/ProvidersTab.d.ts +4 -0
- package/dist/source-control/react/tabs/ProvidersTab.js +10 -0
- package/dist/source-control/rules.d.ts +32 -0
- package/dist/source-control/rules.js +35 -0
- package/dist/source-control/source-control.module.d.ts +36 -0
- package/dist/source-control/source-control.module.js +6 -0
- package/package.json +207 -4
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { mediaRowHandles } from '../../rules.js';
|
|
2
|
+
export function useMediaGrid(props, _optional = {}) {
|
|
3
|
+
const handles = mediaRowHandles({ media: props.actions.map(action => action.item) });
|
|
4
|
+
return { className: props.actions.length ? 'jini-media-grid' : 'jini-media-grid-empty', ...props, actions: props.actions.map((action, index) => ({ ...action, handleBase: handles[index] })) };
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=MediaGrid.hooks.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { MediaAsset } from '../../models.js';
|
|
2
|
+
import type { MediaApiPort } from '../../ports.js';
|
|
3
|
+
export interface MediaLightboxProps {
|
|
4
|
+
readonly items: readonly MediaAsset[];
|
|
5
|
+
readonly api: MediaApiPort;
|
|
6
|
+
readonly activeIndex: number | null;
|
|
7
|
+
readonly onNavigate: (index: number) => void;
|
|
8
|
+
readonly onClose: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function useMediaLightbox(props: MediaLightboxProps, _optional?: Record<string, never>): {
|
|
11
|
+
item: MediaAsset | null;
|
|
12
|
+
open: boolean;
|
|
13
|
+
hasPrev: boolean;
|
|
14
|
+
hasNext: boolean;
|
|
15
|
+
previous: () => void;
|
|
16
|
+
next: () => void;
|
|
17
|
+
items: readonly MediaAsset[];
|
|
18
|
+
api: MediaApiPort;
|
|
19
|
+
activeIndex: number | null;
|
|
20
|
+
onNavigate: (index: number) => void;
|
|
21
|
+
onClose: () => void;
|
|
22
|
+
dialogRef: import("react").RefObject<HTMLDialogElement | null>;
|
|
23
|
+
closeRef: import("react").RefObject<HTMLButtonElement | null>;
|
|
24
|
+
title: string;
|
|
25
|
+
position: string;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=MediaLightbox.hooks.d.ts.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
export function useMediaLightbox(props, _optional = {}) {
|
|
3
|
+
const item = props.activeIndex === null ? null : props.items[props.activeIndex] ?? null;
|
|
4
|
+
function go(index) {
|
|
5
|
+
// Clamps rather than wrapping: staying on the last asset is the less surprising
|
|
6
|
+
// default for an operator navigating a specific set of uploads, not a slideshow.
|
|
7
|
+
if (index >= 0 && index < props.items.length) {
|
|
8
|
+
const focusedPart = dialogRef.current?.ownerDocument.activeElement?.getAttribute('data-jini-part');
|
|
9
|
+
// Keep focus in the dialog when the focused arrow disappears at a boundary.
|
|
10
|
+
// Interior navigation leaves focus where the operator put it.
|
|
11
|
+
if ((index === 0 && focusedPart === 'media.lightbox.previous') ||
|
|
12
|
+
(index === props.items.length - 1 && focusedPart === 'media.lightbox.next'))
|
|
13
|
+
closeRef.current?.focus({ preventScroll: true });
|
|
14
|
+
props.onNavigate(index);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const closeRef = useRef(null);
|
|
18
|
+
const dialogRef = useRef(null);
|
|
19
|
+
const open = !!item;
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
// Close exists at every position, so it is a stable initial focus target. Only
|
|
22
|
+
// opening focuses it; navigation must preserve the operator's current focus.
|
|
23
|
+
if (open)
|
|
24
|
+
closeRef.current?.focus();
|
|
25
|
+
}, [open]);
|
|
26
|
+
// Dialog owns open/close/focus, keyed on open rather than index: navigation must not
|
|
27
|
+
// reopen an already-open dialog or recapture its trigger from inside the lightbox.
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const dialog = dialogRef.current;
|
|
30
|
+
if (!dialog || !item)
|
|
31
|
+
return;
|
|
32
|
+
const onKey = (event) => {
|
|
33
|
+
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')
|
|
34
|
+
return;
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
if (props.activeIndex !== null)
|
|
37
|
+
go(props.activeIndex + (event.key === 'ArrowRight' ? 1 : -1));
|
|
38
|
+
// Native video controls may also seek while focused, as in the legacy lightbox.
|
|
39
|
+
// Preview stage remains private, so do not silently infer it from contentType.
|
|
40
|
+
};
|
|
41
|
+
dialog.ownerDocument.addEventListener('keydown', onKey);
|
|
42
|
+
return () => dialog.ownerDocument.removeEventListener('keydown', onKey);
|
|
43
|
+
}, [props.activeIndex, props.items, props.onNavigate, !!item]);
|
|
44
|
+
return {
|
|
45
|
+
dialogRef,
|
|
46
|
+
closeRef,
|
|
47
|
+
title: item ? `Media preview: ${item.title}` : 'Media preview',
|
|
48
|
+
position: item && props.activeIndex !== null ? `${props.activeIndex + 1} / ${props.items.length}` : '',
|
|
49
|
+
...props,
|
|
50
|
+
item,
|
|
51
|
+
open: !!item,
|
|
52
|
+
hasPrev: props.activeIndex !== null && props.activeIndex > 0,
|
|
53
|
+
hasNext: props.activeIndex !== null && props.activeIndex + 1 < props.items.length,
|
|
54
|
+
previous: () => {
|
|
55
|
+
if (props.activeIndex !== null)
|
|
56
|
+
go(props.activeIndex - 1);
|
|
57
|
+
},
|
|
58
|
+
next: () => {
|
|
59
|
+
if (props.activeIndex !== null)
|
|
60
|
+
go(props.activeIndex + 1);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=MediaLightbox.hooks.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ModulePageProps } from '../../../react/bind-react.js';
|
|
3
|
+
import { createLibraryController } from '../../controllers/library.controller.js';
|
|
4
|
+
import type { LibraryState } from '../../controllers/library.controller.js';
|
|
5
|
+
export declare const MediaLibraryContext: import("react").Context<{
|
|
6
|
+
controller: ReturnType<typeof createLibraryController> | null;
|
|
7
|
+
snapshot: LibraryState | null;
|
|
8
|
+
} | null>;
|
|
9
|
+
export declare function useSharedMediaLibrary(_required?: Record<string, never>, _optional?: Record<string, never>): {
|
|
10
|
+
controller: ReturnType<typeof createLibraryController> | null;
|
|
11
|
+
snapshot: LibraryState | null;
|
|
12
|
+
} | null;
|
|
13
|
+
export interface MediaPageProps extends ModulePageProps {
|
|
14
|
+
readonly headerActions?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare function useMediaPage(props: MediaPageProps, _optional?: Record<string, never>): {
|
|
17
|
+
library: {
|
|
18
|
+
controller: {
|
|
19
|
+
getSnapshot: () => Readonly<LibraryState>;
|
|
20
|
+
subscribe: ({ listener }: {
|
|
21
|
+
listener: () => void;
|
|
22
|
+
}) => () => void;
|
|
23
|
+
load: (_required?: Record<string, never>, _optional?: Record<string, never>) => Promise<void>;
|
|
24
|
+
setQuery({ query }: {
|
|
25
|
+
query: import("../../models.js").MediaQuery;
|
|
26
|
+
}, _optional?: Record<string, never>): Promise<void>;
|
|
27
|
+
upload({ input, alt }: {
|
|
28
|
+
input: import("../../models.js").UploadInput;
|
|
29
|
+
alt?: string;
|
|
30
|
+
}, _optional?: Record<string, never>): Promise<boolean>;
|
|
31
|
+
trash({ id }: {
|
|
32
|
+
id: string;
|
|
33
|
+
}, _optional?: Record<string, never>): Promise<boolean>;
|
|
34
|
+
restore({ id }: {
|
|
35
|
+
id: string;
|
|
36
|
+
}, _optional?: Record<string, never>): Promise<boolean>;
|
|
37
|
+
requestPurge({ item }: {
|
|
38
|
+
item: import("../../models.js").MediaAsset;
|
|
39
|
+
}, _optional?: Record<string, never>): void;
|
|
40
|
+
cancelPurge(_required?: Record<string, never>, _optional?: Record<string, never>): void;
|
|
41
|
+
confirmPurge({ confirmed }: {
|
|
42
|
+
confirmed: boolean;
|
|
43
|
+
}, _optional?: Record<string, never>): Promise<boolean>;
|
|
44
|
+
dispose(_required?: Record<string, never>, _optional?: Record<string, never>): void;
|
|
45
|
+
} | null;
|
|
46
|
+
snapshot: Readonly<LibraryState> | null;
|
|
47
|
+
};
|
|
48
|
+
headerActions: ReactNode;
|
|
49
|
+
activeId: string | undefined;
|
|
50
|
+
tabs: {
|
|
51
|
+
id: string;
|
|
52
|
+
handle: string;
|
|
53
|
+
icon: import("react").FunctionComponentElement<Record<string, never>>;
|
|
54
|
+
count: number | null | undefined;
|
|
55
|
+
selected: boolean;
|
|
56
|
+
onPress: () => void;
|
|
57
|
+
label: string;
|
|
58
|
+
visible: boolean;
|
|
59
|
+
reason: string | null;
|
|
60
|
+
params: Readonly<Record<string, unknown>>;
|
|
61
|
+
agentReachable: boolean;
|
|
62
|
+
}[];
|
|
63
|
+
ActiveTab: import("react").LazyExoticComponent<import("react").ComponentType<import("../../../react/bind-react.js").TabViewProps>> | undefined;
|
|
64
|
+
params: Readonly<Record<string, unknown>>;
|
|
65
|
+
permissions: readonly string[];
|
|
66
|
+
denied: boolean;
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=MediaPage.hooks.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createElement, createContext, useContext, useEffect, useState } from 'react';
|
|
2
|
+
import { useController } from '../../../react/use-controller.js';
|
|
3
|
+
import { createLibraryController } from '../../controllers/library.controller.js';
|
|
4
|
+
import { useMediaPorts } from './MediaPorts.hooks.js';
|
|
5
|
+
import { AllIcon, ImageIcon, VideoIcon, CloudIcon } from '../components/MediaIcons.js';
|
|
6
|
+
import { resolveActiveTab } from '../../rules.js';
|
|
7
|
+
export const MediaLibraryContext = createContext(null);
|
|
8
|
+
export function useSharedMediaLibrary(_required = {}, _optional = {}) {
|
|
9
|
+
return useContext(MediaLibraryContext);
|
|
10
|
+
}
|
|
11
|
+
export function useMediaPage(props, _optional = {}) {
|
|
12
|
+
const [localTab, setLocalTab] = useState('all');
|
|
13
|
+
const { mediaApi, mediaEvents, mediaProviders } = useMediaPorts();
|
|
14
|
+
const library = useController({ create: () => createLibraryController({ api: mediaApi }, { query: { filter: requestedFilter({ tabId: props.requestedTab ?? localTab }) } }), dependencies: [mediaApi] }, { start: ({ controller }) => { if (props.description.visible)
|
|
15
|
+
void controller.load(); } });
|
|
16
|
+
useEffect(() => props.description.visible ? mediaEvents?.subscribe({ onRefresh: () => { void library.controller?.load(); } }) : undefined, [props.description.visible, mediaEvents, library.controller]);
|
|
17
|
+
const [providerCount, setProviderCount] = useState(null);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!props.description.visible || !mediaProviders || !props.description.grants.includes('media.providers'))
|
|
20
|
+
return;
|
|
21
|
+
const abort = new AbortController();
|
|
22
|
+
void mediaProviders.list({}, { signal: abort.signal }).then(items => {
|
|
23
|
+
if (!abort.signal.aborted && items)
|
|
24
|
+
setProviderCount(items.length);
|
|
25
|
+
}).catch(() => { });
|
|
26
|
+
return () => abort.abort();
|
|
27
|
+
}, [mediaProviders, props.description.grants, props.description.visible]);
|
|
28
|
+
const visible = props.description.visible
|
|
29
|
+
? props.description.tabs.filter((tab) => tab.visible)
|
|
30
|
+
: [];
|
|
31
|
+
const requested = resolveActiveTab({ tabId: props.requestedTab ?? localTab });
|
|
32
|
+
const active = visible.find((tab) => tab.id.endsWith(`.${requested}`)) ?? visible[0];
|
|
33
|
+
const tabs = visible.map((tab) => {
|
|
34
|
+
const id = tab.id.slice(tab.id.lastIndexOf('.') + 1);
|
|
35
|
+
return {
|
|
36
|
+
...tab,
|
|
37
|
+
id,
|
|
38
|
+
handle: `media-tab-${id}`,
|
|
39
|
+
icon: createElement(id === 'images' ? ImageIcon : id === 'videos' ? VideoIcon : id === 'external-providers' ? CloudIcon : AllIcon, {}),
|
|
40
|
+
count: id === 'external-providers' ? providerCount : library.snapshot?.counts?.[id],
|
|
41
|
+
selected: active?.id === tab.id,
|
|
42
|
+
onPress: () => {
|
|
43
|
+
setLocalTab(id);
|
|
44
|
+
props.onTabChange?.({ tab: id });
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
const id = active?.id.slice(active.id.lastIndexOf('.') + 1);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (props.description.visible && (id === 'all' || id === 'images' || id === 'videos') && library.controller?.getSnapshot().query.filter !== id)
|
|
51
|
+
void library.controller?.setQuery({ query: { ...library.controller.getSnapshot().query, filter: id } });
|
|
52
|
+
}, [id, library.controller, props.description.visible]);
|
|
53
|
+
return {
|
|
54
|
+
library,
|
|
55
|
+
headerActions: props.headerActions,
|
|
56
|
+
activeId: id,
|
|
57
|
+
tabs,
|
|
58
|
+
ActiveTab: id ? props.tabs[id] : undefined,
|
|
59
|
+
params: active?.params ?? {},
|
|
60
|
+
permissions: props.description.grants,
|
|
61
|
+
denied: !props.description.visible,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function requestedFilter({ tabId }) {
|
|
65
|
+
const tab = resolveActiveTab({ tabId });
|
|
66
|
+
return tab === 'external-providers' ? 'all' : tab;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=MediaPage.hooks.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MediaAsset } from '../../models.js';
|
|
2
|
+
import type { MediaApiPort } from '../../ports.js';
|
|
3
|
+
export interface MediaPickerProps {
|
|
4
|
+
readonly api: MediaApiPort;
|
|
5
|
+
readonly accept: readonly string[];
|
|
6
|
+
readonly onChoose: (asset: MediaAsset | null) => void;
|
|
7
|
+
readonly onClose: () => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function useMediaPicker(props: MediaPickerProps, _optional?: Record<string, never>): {
|
|
10
|
+
snapshot: Readonly<import("../../index.js").LibraryState> | null;
|
|
11
|
+
actions: {
|
|
12
|
+
item: MediaAsset;
|
|
13
|
+
onChoose: () => void;
|
|
14
|
+
}[];
|
|
15
|
+
loading: boolean;
|
|
16
|
+
onRetry: () => void;
|
|
17
|
+
onSearch: ({ value: search }: {
|
|
18
|
+
value: string;
|
|
19
|
+
}) => void;
|
|
20
|
+
search: string;
|
|
21
|
+
api: MediaApiPort;
|
|
22
|
+
accept: readonly string[];
|
|
23
|
+
onChoose: (asset: MediaAsset | null) => void;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=MediaPicker.hooks.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useController } from '../../../react/use-controller.js';
|
|
2
|
+
import { createLibraryController } from '../../controllers/library.controller.js';
|
|
3
|
+
import { acceptsMedia } from '../../rules.js';
|
|
4
|
+
export function useMediaPicker(props, _optional = {}) {
|
|
5
|
+
const { controller, snapshot } = useController({ create: () => createLibraryController({ api: props.api }), dependencies: [props.api] }, {
|
|
6
|
+
start: ({ controller }) => {
|
|
7
|
+
void controller.load();
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
const actions = (snapshot?.items ?? [])
|
|
11
|
+
.filter((item) => item.status === 'active' && acceptsMedia({ item, accept: props.accept }))
|
|
12
|
+
.map((item) => ({ item, onChoose: () => props.onChoose(item) }));
|
|
13
|
+
return {
|
|
14
|
+
...props,
|
|
15
|
+
snapshot,
|
|
16
|
+
actions,
|
|
17
|
+
loading: !snapshot || (snapshot.loading && !snapshot.error),
|
|
18
|
+
onRetry: () => { void controller?.load(); },
|
|
19
|
+
onSearch: ({ value: search }) => {
|
|
20
|
+
void controller?.setQuery({ query: { search } });
|
|
21
|
+
},
|
|
22
|
+
search: snapshot?.query.search ?? '',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=MediaPicker.hooks.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MediaApiPort, MediaProvidersPort, MediaEventsPort } from '../../ports.js';
|
|
2
|
+
export interface MediaPorts {
|
|
3
|
+
readonly mediaApi: MediaApiPort;
|
|
4
|
+
readonly mediaProviders?: MediaProvidersPort;
|
|
5
|
+
readonly mediaEvents?: MediaEventsPort;
|
|
6
|
+
}
|
|
7
|
+
export declare const MediaPortsContext: import("react").Context<MediaPorts | null>;
|
|
8
|
+
export declare function useMediaPorts(_required?: Record<string, never>, _optional?: Record<string, never>): MediaPorts;
|
|
9
|
+
//# sourceMappingURL=MediaPorts.hooks.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import { AdminConfigError } from '../../../core/module/index.js';
|
|
3
|
+
export const MediaPortsContext = createContext(null);
|
|
4
|
+
export function useMediaPorts(_required = {}, _optional = {}) {
|
|
5
|
+
const ports = useContext(MediaPortsContext);
|
|
6
|
+
if (!ports)
|
|
7
|
+
throw new AdminConfigError({ issues: ['React scope unavailable: media'] });
|
|
8
|
+
return ports;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=MediaPorts.hooks.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Confirmation safety moved to ui-kit's framework-free controller. Cancel-first focus,
|
|
2
|
+
* pending dismissal/activation and trigger restoration remain enforced for every view. */
|
|
3
|
+
export interface MediaPurgeDialogProps {
|
|
4
|
+
readonly filename?: string;
|
|
5
|
+
readonly open: boolean;
|
|
6
|
+
readonly pending: boolean;
|
|
7
|
+
readonly onCancel: () => void;
|
|
8
|
+
readonly onConfirm: () => void | Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export declare function useMediaPurgeDialog(props: MediaPurgeDialogProps, _optional?: Record<string, never>): {
|
|
11
|
+
actionAccessibleNames: {
|
|
12
|
+
cancel: string;
|
|
13
|
+
confirm: string;
|
|
14
|
+
};
|
|
15
|
+
consequence: string;
|
|
16
|
+
filename?: string;
|
|
17
|
+
open: boolean;
|
|
18
|
+
pending: boolean;
|
|
19
|
+
onCancel: () => void;
|
|
20
|
+
onConfirm: () => void | Promise<void>;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=MediaPurgeDialog.hooks.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function useMediaPurgeDialog(props, _optional = {}) {
|
|
2
|
+
return { ...props, actionAccessibleNames: { cancel: 'Cancel', confirm: 'Delete permanently' }, consequence: props.filename
|
|
3
|
+
? `Permanently delete "${props.filename}"? This cannot be undone.`
|
|
4
|
+
: 'This permanently deletes the file. This cannot be undone.' };
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=MediaPurgeDialog.hooks.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ChangeEvent } from 'react';
|
|
2
|
+
export declare function useProvidersTab(_required?: Record<string, never>, _optional?: Record<string, never>): {
|
|
3
|
+
rows: {
|
|
4
|
+
divider: boolean;
|
|
5
|
+
statusLabel: string | null;
|
|
6
|
+
statusClassName: string;
|
|
7
|
+
credential: string;
|
|
8
|
+
credentialType: "text" | "password";
|
|
9
|
+
credentialPlaceholder: string;
|
|
10
|
+
credentialAttrs: {
|
|
11
|
+
'data-jini-part': string;
|
|
12
|
+
'data-agent-private': boolean;
|
|
13
|
+
'data-agent-element': string;
|
|
14
|
+
'aria-label': string;
|
|
15
|
+
};
|
|
16
|
+
toggleLabel: string;
|
|
17
|
+
visible: boolean;
|
|
18
|
+
toggle(): void;
|
|
19
|
+
onCredential: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
20
|
+
baseUrl: string;
|
|
21
|
+
baseUrlPlaceholder: string;
|
|
22
|
+
baseUrlLabel: string;
|
|
23
|
+
onBaseUrl: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
24
|
+
model: string;
|
|
25
|
+
modelLabel: string;
|
|
26
|
+
modelsId: string;
|
|
27
|
+
hasModels: boolean;
|
|
28
|
+
onModel: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
29
|
+
clearLabel: string;
|
|
30
|
+
clearDisabled: boolean;
|
|
31
|
+
clear: () => void;
|
|
32
|
+
invalid: boolean;
|
|
33
|
+
hint: string | null;
|
|
34
|
+
hintClassName: string;
|
|
35
|
+
hintRole: "alert" | undefined;
|
|
36
|
+
ariaInvalid: true | undefined;
|
|
37
|
+
id: string;
|
|
38
|
+
label: string;
|
|
39
|
+
defaultBaseUrl?: string;
|
|
40
|
+
models?: readonly string[];
|
|
41
|
+
}[];
|
|
42
|
+
reload: () => void;
|
|
43
|
+
reloadDisabled: boolean;
|
|
44
|
+
reloadLabel: string;
|
|
45
|
+
unreachable: boolean;
|
|
46
|
+
empty: boolean;
|
|
47
|
+
save: () => void;
|
|
48
|
+
saveLabel: string;
|
|
49
|
+
saveDisabled: boolean;
|
|
50
|
+
saved: boolean;
|
|
51
|
+
saveError: boolean;
|
|
52
|
+
disabled: boolean;
|
|
53
|
+
settingsDisabled: boolean;
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=ProvidersTab.hooks.d.ts.map
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { useMediaProvidersTab, sortProvidersByConfigured, isEntryPresent, isMarkerOnlyEntry, maskedKeyLabel, isProviderBaseUrlInvalid, invalidBaseUrlProviderIds } from '@jini-ai/ui';
|
|
3
|
+
import { useMediaPorts } from './MediaPorts.hooks.js';
|
|
4
|
+
function configuration({ items }, _optional = {}) {
|
|
5
|
+
return Object.fromEntries(items.filter(item => item.configured || item.apiKeyTail || item.baseUrl?.trim() || item.model?.trim())
|
|
6
|
+
.map(item => [item.id, { apiKeyConfigured: item.configured,
|
|
7
|
+
...(item.apiKeyTail === undefined ? {} : { apiKeyTail: item.apiKeyTail }),
|
|
8
|
+
...(item.baseUrl === undefined ? {} : { baseUrl: item.baseUrl }),
|
|
9
|
+
...(item.model === undefined ? {} : { model: item.model }) }]));
|
|
10
|
+
}
|
|
11
|
+
export function useProvidersTab(_required = {}, _optional = {}) {
|
|
12
|
+
const { mediaProviders } = useMediaPorts();
|
|
13
|
+
const [discoveredCatalog, setDiscoveredCatalog] = useState([]);
|
|
14
|
+
const [visibleKeys, setVisibleKeys] = useState(() => new Set());
|
|
15
|
+
const lifetime = useRef(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const abort = new AbortController();
|
|
18
|
+
lifetime.current = abort;
|
|
19
|
+
return () => abort.abort();
|
|
20
|
+
}, [mediaProviders]);
|
|
21
|
+
// Always invoke the hook. An unavailable optional port uses an inert, scoped fallback.
|
|
22
|
+
// Reuse the established editor's send-time serialization, reload merge and clear rollback.
|
|
23
|
+
const editorPort = useMemo(() => {
|
|
24
|
+
let lastRead = [];
|
|
25
|
+
return {
|
|
26
|
+
async fetchMediaProviders() {
|
|
27
|
+
try {
|
|
28
|
+
const signal = lifetime.current.signal;
|
|
29
|
+
const items = await mediaProviders?.list({}, { signal });
|
|
30
|
+
if (!items || signal.aborted)
|
|
31
|
+
return null;
|
|
32
|
+
lastRead = items;
|
|
33
|
+
setDiscoveredCatalog(items.map(({ id, label }) => ({ id, label })));
|
|
34
|
+
return configuration({ items });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
async saveMediaProviders(providers) {
|
|
41
|
+
if (!mediaProviders)
|
|
42
|
+
throw new Error('Provider service unavailable');
|
|
43
|
+
const signal = lifetime.current.signal;
|
|
44
|
+
if (mediaProviders.saveChanges) {
|
|
45
|
+
const items = await mediaProviders.saveChanges({ providers }, { signal });
|
|
46
|
+
lastRead = items;
|
|
47
|
+
return configuration({ items });
|
|
48
|
+
}
|
|
49
|
+
// Older hosts retain the one-button editor; writes remain sequential and failures
|
|
50
|
+
// retain local edits. Atomic whole-set hosts should implement saveChanges instead.
|
|
51
|
+
for (const item of lastRead) {
|
|
52
|
+
const entry = providers[item.id];
|
|
53
|
+
if (!entry) {
|
|
54
|
+
if (item.configured || item.baseUrl || item.model)
|
|
55
|
+
await mediaProviders.removeCredential({ id: item.id }, { signal });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if ((entry.baseUrl ?? '') !== (item.baseUrl ?? '') || (entry.model ?? '') !== (item.model ?? '')) {
|
|
59
|
+
if (!mediaProviders.saveSettings)
|
|
60
|
+
throw new Error('Provider settings unavailable');
|
|
61
|
+
await mediaProviders.saveSettings({ id: item.id, baseUrl: entry.baseUrl ?? '', model: entry.model ?? '' }, { signal });
|
|
62
|
+
}
|
|
63
|
+
if (entry.apiKey?.trim())
|
|
64
|
+
await mediaProviders.saveCredential({ id: item.id, credential: entry.apiKey }, { signal });
|
|
65
|
+
}
|
|
66
|
+
const items = await mediaProviders.list({}, { signal });
|
|
67
|
+
if (!items)
|
|
68
|
+
throw new Error('Provider service unavailable');
|
|
69
|
+
lastRead = items;
|
|
70
|
+
return configuration({ items });
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}, [mediaProviders]);
|
|
74
|
+
const editor = useMediaProvidersTab({ port: editorPort });
|
|
75
|
+
const catalog = mediaProviders?.catalog ?? discoveredCatalog;
|
|
76
|
+
const pinnedIds = mediaProviders?.pinnedProviderIds ?? [];
|
|
77
|
+
const ordered = sortProvidersByConfigured(catalog, editor.providers, pinnedIds);
|
|
78
|
+
const rows = ordered.map((item, index) => {
|
|
79
|
+
const entry = editor.providers[item.id] ?? {};
|
|
80
|
+
const saved = isMarkerOnlyEntry(entry);
|
|
81
|
+
const mask = saved ? maskedKeyLabel(entry) : null;
|
|
82
|
+
const visible = visibleKeys.has(item.id);
|
|
83
|
+
const invalid = isProviderBaseUrlInvalid(entry);
|
|
84
|
+
const modelsId = `jini-media-provider-models-${item.id}`;
|
|
85
|
+
return {
|
|
86
|
+
...item,
|
|
87
|
+
divider: index > 0 && !pinnedIds.includes(item.id) && pinnedIds.includes(ordered[index - 1].id),
|
|
88
|
+
statusLabel: saved ? `Saved (${mask})` : editor.pendingProviderIds.has(item.id) ? 'Unsaved' : null,
|
|
89
|
+
statusClassName: saved ? 'jini-field-status-badge jini-field-status-badge-success' : 'jini-field-status-badge',
|
|
90
|
+
credential: entry.apiKey ?? '', credentialType: visible ? 'text' : 'password',
|
|
91
|
+
credentialPlaceholder: mask ?? 'Paste your API key',
|
|
92
|
+
credentialAttrs: { 'data-jini-part': 'media.provider.credential', 'data-agent-private': true,
|
|
93
|
+
'data-agent-element': `media-provider-${item.id}-api-key`, 'aria-label': `${item.label} credential` },
|
|
94
|
+
toggleLabel: `${item.label} ${visible ? 'Hide' : 'Show'}`, visible,
|
|
95
|
+
toggle() { setVisibleKeys(current => { const next = new Set(current); if (next.has(item.id))
|
|
96
|
+
next.delete(item.id);
|
|
97
|
+
else
|
|
98
|
+
next.add(item.id); return next; }); },
|
|
99
|
+
onCredential: (event) => editor.updateProvider(item.id, { apiKey: event.currentTarget.value }),
|
|
100
|
+
baseUrl: entry.baseUrl ?? '', baseUrlPlaceholder: item.defaultBaseUrl || 'https://api.example.com',
|
|
101
|
+
baseUrlLabel: `${item.label} base URL`,
|
|
102
|
+
onBaseUrl: (event) => editor.updateProvider(item.id, { baseUrl: event.currentTarget.value }),
|
|
103
|
+
model: entry.model ?? '', modelLabel: `${item.label} model`, modelsId, hasModels: !!item.models?.length,
|
|
104
|
+
onModel: (event) => editor.updateProvider(item.id, { model: event.currentTarget.value }),
|
|
105
|
+
clearLabel: `${item.label} Clear`, clearDisabled: !isEntryPresent(entry) || !mediaProviders,
|
|
106
|
+
clear: () => editor.clearProvider(item.id),
|
|
107
|
+
invalid, hint: invalid ? 'Enter an absolute http:// or https:// URL that is not a private or internal address.'
|
|
108
|
+
: !entry.baseUrl?.trim() && item.defaultBaseUrl ? `Uses ${item.defaultBaseUrl} by default.` : null,
|
|
109
|
+
hintClassName: invalid ? 'jini-field-hint jini-hint-error' : 'jini-field-hint',
|
|
110
|
+
hintRole: invalid ? 'alert' : undefined,
|
|
111
|
+
ariaInvalid: invalid || undefined,
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
return { rows, reload: editor.reload, reloadDisabled: editor.load.status === 'loading',
|
|
115
|
+
reloadLabel: editor.load.status === 'loading' ? 'Reloading…' : 'Reload',
|
|
116
|
+
unreachable: editor.load.status === 'unreachable', empty: !editor.hasAnyConfigured,
|
|
117
|
+
save: editor.saveChanges, saveLabel: editor.save.status === 'saving' ? 'Saving…' : 'Save changes',
|
|
118
|
+
saveDisabled: !mediaProviders || editor.save.status === 'saving' || !editor.pendingProviderIds.size || !!invalidBaseUrlProviderIds(editor.providers).length,
|
|
119
|
+
saved: editor.save.status === 'saved', saveError: editor.save.status === 'save-error', disabled: !mediaProviders,
|
|
120
|
+
// Fail closed: a host that can persist neither the whole set nor per-provider settings
|
|
121
|
+
// must not accept endpoint/model edits that would only surface as a failed save.
|
|
122
|
+
settingsDisabled: !mediaProviders || (!mediaProviders.saveChanges && !mediaProviders.saveSettings) };
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=ProvidersTab.hooks.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ChangeEvent, DragEvent } from 'react';
|
|
2
|
+
import type { UploadInput } from '../../models.js';
|
|
3
|
+
export interface UploadButtonProps {
|
|
4
|
+
readonly upload: (required: {
|
|
5
|
+
input: UploadInput;
|
|
6
|
+
alt?: string;
|
|
7
|
+
}, optional?: Record<string, never>) => Promise<boolean>;
|
|
8
|
+
readonly disabled?: boolean;
|
|
9
|
+
readonly label?: string;
|
|
10
|
+
readonly multiple?: boolean;
|
|
11
|
+
/** Replacement keeps the asset's metadata, so its toolbar has no alt input to fill. */
|
|
12
|
+
readonly withAlt?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Reads a browser File at the React boundary; headless controllers only receive bytes. */
|
|
15
|
+
export declare function readMediaFile({ file }: {
|
|
16
|
+
file: File;
|
|
17
|
+
}, { signal }?: {
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}): Promise<UploadInput>;
|
|
20
|
+
export declare function useUploadButton(props: UploadButtonProps, _optional?: Record<string, never>): {
|
|
21
|
+
alt: string;
|
|
22
|
+
withAlt: boolean;
|
|
23
|
+
multiple: boolean;
|
|
24
|
+
chooseLabel: string;
|
|
25
|
+
altLabel: string;
|
|
26
|
+
handles: {
|
|
27
|
+
toolbar: string;
|
|
28
|
+
file: string;
|
|
29
|
+
alt: string;
|
|
30
|
+
submit: string;
|
|
31
|
+
};
|
|
32
|
+
selectedFileName: string;
|
|
33
|
+
onUpload: () => void;
|
|
34
|
+
onDragOver: (event: DragEvent) => void;
|
|
35
|
+
onDrop: (event: DragEvent) => void;
|
|
36
|
+
uploadDisabled: boolean;
|
|
37
|
+
setAlt: ({ value }: {
|
|
38
|
+
value: string;
|
|
39
|
+
}) => void;
|
|
40
|
+
inputRef: import("react").RefObject<HTMLInputElement | null>;
|
|
41
|
+
onFile: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
42
|
+
error: string | null;
|
|
43
|
+
success: string | null;
|
|
44
|
+
disabled: boolean;
|
|
45
|
+
onPress: () => void | undefined;
|
|
46
|
+
label: string;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=UploadButton.hooks.d.ts.map
|