@jini-ai/admin 0.4.2 → 0.4.4
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 +15 -0
- package/README.md +7 -0
- package/dist/agent-plugins/react/components/AgentPluginListPanel.d.ts +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.js +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.d.ts +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.d.ts +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.js +1 -1
- package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.d.ts +1 -1
- package/dist/agent-plugins/react/index.js +1 -1
- package/dist/agent-plugins/react/pages/AgentPluginsPage.d.ts +1 -1
- package/dist/agent-plugins/react/tabs/DownloadedTab.d.ts +1 -1
- package/dist/agent-plugins/react/tabs/InstalledTab.d.ts +1 -1
- package/dist/agent-plugins/react/tabs/MarketplaceTab.d.ts +1 -1
- package/dist/comments/adapters/http.d.ts +29 -0
- package/dist/comments/adapters/http.js +50 -0
- package/dist/comments/adapters/memory.d.ts +17 -0
- package/dist/comments/adapters/memory.js +61 -0
- package/dist/comments/comments.module.d.ts +73 -0
- package/dist/comments/comments.module.js +16 -0
- package/dist/comments/conformance/comments-api.conformance.d.ts +9 -0
- package/dist/comments/conformance/comments-api.conformance.js +63 -0
- package/dist/comments/controllers/comment-queue.controller.d.ts +48 -0
- package/dist/comments/controllers/comment-queue.controller.js +164 -0
- package/dist/comments/controllers/comment-settings.controller.d.ts +32 -0
- package/dist/comments/controllers/comment-settings.controller.js +77 -0
- package/dist/comments/controllers/comments.controller.d.ts +16 -0
- package/dist/comments/controllers/comments.controller.js +16 -0
- package/dist/comments/index.d.ts +13 -0
- package/dist/comments/index.js +8 -0
- package/dist/comments/messages.en.d.ts +54 -0
- package/dist/comments/messages.en.js +56 -0
- package/dist/comments/models.d.ts +22 -0
- package/dist/comments/models.js +2 -0
- package/dist/comments/ports.d.ts +14 -0
- package/dist/comments/ports.js +5 -0
- package/dist/comments/react/components/QueueSection.d.ts +30 -0
- package/dist/comments/react/components/QueueSection.js +57 -0
- package/dist/comments/react/components/SettingsSection.d.ts +14 -0
- package/dist/comments/react/components/SettingsSection.js +23 -0
- package/dist/comments/react/hooks/CommentsPage.hooks.d.ts +9 -0
- package/dist/comments/react/hooks/CommentsPage.hooks.js +10 -0
- package/dist/comments/react/hooks/CommentsPorts.hooks.d.ts +13 -0
- package/dist/comments/react/hooks/CommentsPorts.hooks.js +15 -0
- package/dist/comments/react/hooks/QueueSection.hooks.d.ts +62 -0
- package/dist/comments/react/hooks/QueueSection.hooks.js +57 -0
- package/dist/comments/react/hooks/SettingsSection.hooks.d.ts +12 -0
- package/dist/comments/react/hooks/SettingsSection.hooks.js +21 -0
- package/dist/comments/react/hooks/use-comment-queue.hooks.d.ts +34 -0
- package/dist/comments/react/hooks/use-comment-queue.hooks.js +47 -0
- package/dist/comments/react/hooks/use-comment-settings.hooks.d.ts +22 -0
- package/dist/comments/react/hooks/use-comment-settings.hooks.js +30 -0
- package/dist/comments/react/hooks/use-comments.hooks.d.ts +15 -0
- package/dist/comments/react/hooks/use-comments.hooks.js +20 -0
- package/dist/comments/react/index.d.ts +316 -0
- package/dist/comments/react/index.js +35 -0
- package/dist/comments/react/pages/CommentsPage.d.ts +12 -0
- package/dist/comments/react/pages/CommentsPage.js +15 -0
- package/dist/comments/rules.d.ts +140 -0
- package/dist/comments/rules.js +199 -0
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.js +1 -0
- package/dist/core/ledger-slice.d.ts +90 -0
- package/dist/core/ledger-slice.js +81 -0
- package/dist/core/ports/comments.d.ts +2 -0
- package/dist/core/ports/forms.d.ts +19 -7
- package/dist/core/ports/forms.js +4 -4
- package/dist/core/ports/index.d.ts +1 -1
- package/dist/core/ports/seo.d.ts +33 -6
- package/dist/core/react/bind-react.d.ts +46 -0
- package/dist/core/react/bind-react.js +28 -0
- package/dist/core/react/index.d.ts +3 -0
- package/dist/core/react/index.js +3 -0
- package/dist/core/react/use-controller.d.ts +16 -0
- package/dist/core/react/use-controller.js +18 -0
- package/dist/forms/adapters/http.d.ts +26 -0
- package/dist/forms/adapters/http.js +43 -0
- package/dist/forms/adapters/memory.d.ts +14 -0
- package/dist/forms/adapters/memory.js +77 -0
- package/dist/forms/conformance/forms-api.conformance.d.ts +17 -0
- package/dist/forms/conformance/forms-api.conformance.js +71 -0
- package/dist/forms/controllers/draft-store.d.ts +18 -0
- package/dist/forms/controllers/draft-store.js +17 -0
- package/dist/forms/controllers/field-attributes-dialog.controller.d.ts +37 -0
- package/dist/forms/controllers/field-attributes-dialog.controller.js +27 -0
- package/dist/forms/controllers/form-editor.controller.d.ts +36 -0
- package/dist/forms/controllers/form-editor.controller.js +22 -0
- package/dist/forms/controllers/form-fields-editor.controller.d.ts +20 -0
- package/dist/forms/controllers/form-fields-editor.controller.js +10 -0
- package/dist/forms/controllers/form-submission-detail.controller.d.ts +20 -0
- package/dist/forms/controllers/form-submission-detail.controller.js +10 -0
- package/dist/forms/controllers/form-submissions.controller.d.ts +25 -0
- package/dist/forms/controllers/form-submissions.controller.js +10 -0
- package/dist/forms/controllers/forms-list.controller.d.ts +22 -0
- package/dist/forms/controllers/forms-list.controller.js +10 -0
- package/dist/forms/forms.module.d.ts +138 -0
- package/dist/forms/forms.module.js +17 -0
- package/dist/forms/html-rules.d.ts +34 -0
- package/dist/forms/html-rules.js +34 -0
- package/dist/forms/index.d.ts +14 -0
- package/dist/forms/index.js +12 -0
- package/dist/forms/messages.en.d.ts +101 -0
- package/dist/forms/messages.en.js +105 -0
- package/dist/forms/models.d.ts +29 -0
- package/dist/forms/models.js +8 -0
- package/dist/forms/ports.d.ts +26 -0
- package/dist/forms/ports.js +6 -0
- package/dist/forms/react/components/FieldAttributesDialog.d.ts +14 -0
- package/dist/forms/react/components/FieldAttributesDialog.js +47 -0
- package/dist/forms/react/components/FormEditorFieldsBody.d.ts +28 -0
- package/dist/forms/react/components/FormEditorFieldsBody.js +24 -0
- package/dist/forms/react/components/FormEditorHeaderText.d.ts +7 -0
- package/dist/forms/react/components/FormEditorHeaderText.js +8 -0
- package/dist/forms/react/components/FormEditorMainPanel.d.ts +12 -0
- package/dist/forms/react/components/FormEditorMainPanel.js +13 -0
- package/dist/forms/react/components/FormEditorTabStrip.d.ts +13 -0
- package/dist/forms/react/components/FormEditorTabStrip.js +14 -0
- package/dist/forms/react/components/FormFieldsEditor.d.ts +13 -0
- package/dist/forms/react/components/FormFieldsEditor.js +39 -0
- package/dist/forms/react/components/FormSubmissionDate.d.ts +8 -0
- package/dist/forms/react/components/FormSubmissionDate.js +5 -0
- package/dist/forms/react/components/FormSubmissionDetail.d.ts +15 -0
- package/dist/forms/react/components/FormSubmissionDetail.js +30 -0
- package/dist/forms/react/components/FormSubmissions.d.ts +12 -0
- package/dist/forms/react/components/FormSubmissions.js +46 -0
- package/dist/forms/react/hooks/FormsPorts.hooks.d.ts +41 -0
- package/dist/forms/react/hooks/FormsPorts.hooks.js +16 -0
- package/dist/forms/react/hooks/forms-view.hooks.d.ts +117 -0
- package/dist/forms/react/hooks/forms-view.hooks.js +78 -0
- package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.d.ts +31 -0
- package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.js +22 -0
- package/dist/forms/react/hooks/use-form-editor.hooks.d.ts +118 -0
- package/dist/forms/react/hooks/use-form-editor.hooks.js +208 -0
- package/dist/forms/react/hooks/use-form-fields-editor.hooks.d.ts +34 -0
- package/dist/forms/react/hooks/use-form-fields-editor.hooks.js +36 -0
- package/dist/forms/react/hooks/use-form-submission-date.hooks.d.ts +12 -0
- package/dist/forms/react/hooks/use-form-submission-date.hooks.js +9 -0
- package/dist/forms/react/hooks/use-form-submission-detail.hooks.d.ts +68 -0
- package/dist/forms/react/hooks/use-form-submission-detail.hooks.js +81 -0
- package/dist/forms/react/hooks/use-form-submissions.hooks.d.ts +67 -0
- package/dist/forms/react/hooks/use-form-submissions.hooks.js +110 -0
- package/dist/forms/react/hooks/use-forms-list.hooks.d.ts +78 -0
- package/dist/forms/react/hooks/use-forms-list.hooks.js +103 -0
- package/dist/forms/react/index.d.ts +452 -0
- package/dist/forms/react/index.js +35 -0
- package/dist/forms/react/pages/FormEditor.d.ts +19 -0
- package/dist/forms/react/pages/FormEditor.js +40 -0
- package/dist/forms/react/pages/FormsList.d.ts +39 -0
- package/dist/forms/react/pages/FormsList.js +50 -0
- package/dist/forms/rules.d.ts +291 -0
- package/dist/forms/rules.js +338 -0
- package/dist/media/react/hooks/EditMediaPanel.hooks.js +1 -1
- package/dist/media/react/hooks/LibraryTab.hooks.d.ts +1 -1
- package/dist/media/react/hooks/LibraryTab.hooks.js +1 -1
- package/dist/media/react/hooks/MediaCard.hooks.js +6 -20
- package/dist/media/react/hooks/MediaGrid.hooks.d.ts +2 -2
- package/dist/media/react/hooks/MediaPage.hooks.d.ts +1 -1
- package/dist/media/react/hooks/MediaPage.hooks.js +1 -1
- package/dist/media/react/hooks/MediaPicker.hooks.js +1 -1
- package/dist/media/react/index.js +1 -1
- package/dist/media/react/tabs/LibraryTab.d.ts +1 -1
- package/dist/media/react/tabs/ProvidersTab.d.ts +1 -1
- package/dist/playground/react/components/Canvas.d.ts +1 -1
- package/dist/playground/react/hooks/Canvas.hooks.d.ts +1 -1
- package/dist/playground/react/hooks/Canvas.hooks.js +1 -1
- package/dist/playground/react/hooks/PlaygroundPage.hooks.d.ts +1 -1
- package/dist/playground/react/index.js +1 -1
- package/dist/playground/react/pages/PlaygroundPage.d.ts +1 -1
- package/dist/playground/react/tabs/CanvasTab.d.ts +1 -1
- package/dist/react/bind-react.d.ts +1 -45
- package/dist/react/bind-react.js +2 -27
- package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +22 -5
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +2 -2
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +17 -55
- package/dist/react/components/ConfirmDialog/ConfirmDialog.js +33 -70
- package/dist/react/components/RowMenu/RowMenu.hooks.js +14 -3
- package/dist/react/use-controller.d.ts +1 -15
- package/dist/react/use-controller.js +2 -17
- package/dist/redirects/adapters/http.d.ts +20 -0
- package/dist/redirects/adapters/http.js +31 -0
- package/dist/redirects/adapters/memory.d.ts +13 -0
- package/dist/redirects/adapters/memory.js +83 -0
- package/dist/redirects/conformance/redirects-api.conformance.d.ts +12 -0
- package/dist/redirects/conformance/redirects-api.conformance.js +66 -0
- package/dist/redirects/controllers/hit-count.controller.d.ts +14 -0
- package/dist/redirects/controllers/hit-count.controller.js +10 -0
- package/dist/redirects/controllers/import-redirects.controller.d.ts +28 -0
- package/dist/redirects/controllers/import-redirects.controller.js +29 -0
- package/dist/redirects/controllers/redirects.controller.d.ts +37 -0
- package/dist/redirects/controllers/redirects.controller.js +38 -0
- package/dist/redirects/index.d.ts +11 -0
- package/dist/redirects/index.js +10 -0
- package/dist/redirects/messages.en.d.ts +58 -0
- package/dist/redirects/messages.en.js +60 -0
- package/dist/redirects/models.d.ts +14 -0
- package/dist/redirects/models.js +2 -0
- package/dist/redirects/ports.d.ts +9 -0
- package/dist/redirects/ports.js +4 -0
- package/dist/redirects/react/components/HitCountCell.d.ts +19 -0
- package/dist/redirects/react/components/HitCountCell.js +19 -0
- package/dist/redirects/react/components/ImportRedirectsForm.d.ts +17 -0
- package/dist/redirects/react/components/ImportRedirectsForm.js +12 -0
- package/dist/redirects/react/hooks/RedirectsOptions.hooks.d.ts +27 -0
- package/dist/redirects/react/hooks/RedirectsOptions.hooks.js +15 -0
- package/dist/redirects/react/hooks/RedirectsPage.hooks.d.ts +50 -0
- package/dist/redirects/react/hooks/RedirectsPage.hooks.js +30 -0
- package/dist/redirects/react/hooks/RedirectsPorts.hooks.d.ts +10 -0
- package/dist/redirects/react/hooks/RedirectsPorts.hooks.js +11 -0
- package/dist/redirects/react/hooks/use-hit-count-cell.hooks.d.ts +19 -0
- package/dist/redirects/react/hooks/use-hit-count-cell.hooks.js +15 -0
- package/dist/redirects/react/hooks/use-import-redirects-form.hooks.d.ts +21 -0
- package/dist/redirects/react/hooks/use-import-redirects-form.hooks.js +25 -0
- package/dist/redirects/react/hooks/use-redirects.hooks.d.ts +34 -0
- package/dist/redirects/react/hooks/use-redirects.hooks.js +63 -0
- package/dist/redirects/react/hooks/wired.hooks.d.ts +55 -0
- package/dist/redirects/react/hooks/wired.hooks.js +31 -0
- package/dist/redirects/react/index.d.ts +324 -0
- package/dist/redirects/react/index.js +28 -0
- package/dist/redirects/react/pages/RedirectsPage.d.ts +15 -0
- package/dist/redirects/react/pages/RedirectsPage.js +20 -0
- package/dist/redirects/redirects.module.d.ts +77 -0
- package/dist/redirects/redirects.module.js +13 -0
- package/dist/redirects/rules.d.ts +131 -0
- package/dist/redirects/rules.js +134 -0
- package/dist/security/react/hooks/AccessTokensTab.hooks.d.ts +1 -1
- package/dist/security/react/hooks/AccessTokensTab.hooks.js +1 -1
- package/dist/security/react/hooks/RootKeyTab.hooks.d.ts +1 -1
- package/dist/security/react/hooks/RootKeyTab.hooks.js +1 -1
- package/dist/security/react/hooks/SecurityPage.hooks.d.ts +1 -1
- package/dist/security/react/index.js +1 -1
- package/dist/security/react/pages/SecurityPage.d.ts +1 -1
- package/dist/security/react/tabs/AccessTokensTab.d.ts +1 -1
- package/dist/security/react/tabs/RootKeyTab.d.ts +1 -1
- package/dist/seo/adapters/http.d.ts +31 -0
- package/dist/seo/adapters/http.js +37 -0
- package/dist/seo/adapters/memory.d.ts +28 -0
- package/dist/seo/adapters/memory.js +129 -0
- package/dist/seo/conformance/seo-api.conformance.d.ts +8 -0
- package/dist/seo/conformance/seo-api.conformance.js +44 -0
- package/dist/seo/controllers/entry-picker.controller.d.ts +21 -0
- package/dist/seo/controllers/entry-picker.controller.js +17 -0
- package/dist/seo/controllers/entry-section.controller.d.ts +20 -0
- package/dist/seo/controllers/entry-section.controller.js +7 -0
- package/dist/seo/controllers/media-ref.controller.d.ts +26 -0
- package/dist/seo/controllers/media-ref.controller.js +14 -0
- package/dist/seo/controllers/seo-entry.controller.d.ts +31 -0
- package/dist/seo/controllers/seo-entry.controller.js +52 -0
- package/dist/seo/controllers/seo.controller.d.ts +29 -0
- package/dist/seo/controllers/seo.controller.js +50 -0
- package/dist/seo/controllers/sitemap.controller.d.ts +25 -0
- package/dist/seo/controllers/sitemap.controller.js +27 -0
- package/dist/seo/index.d.ts +14 -0
- package/dist/seo/index.js +12 -0
- package/dist/seo/messages.en.d.ts +79 -0
- package/dist/seo/messages.en.js +79 -0
- package/dist/seo/models.d.ts +179 -0
- package/dist/seo/models.js +8 -0
- package/dist/seo/ports.d.ts +11 -0
- package/dist/seo/ports.js +4 -0
- package/dist/seo/react/components/MediaPickerBridge.d.ts +4 -0
- package/dist/seo/react/components/MediaPickerBridge.js +8 -0
- package/dist/seo/react/components/MediaRefField.d.ts +40 -0
- package/dist/seo/react/components/MediaRefField.js +12 -0
- package/dist/seo/react/components/SeoIcons.d.ts +13 -0
- package/dist/seo/react/components/SeoIcons.js +32 -0
- package/dist/seo/react/components/SitemapModal.d.ts +48 -0
- package/dist/seo/react/components/SitemapModal.js +72 -0
- package/dist/seo/react/hooks/MediaPickerBridge.hooks.d.ts +6 -0
- package/dist/seo/react/hooks/MediaPickerBridge.hooks.js +27 -0
- package/dist/seo/react/hooks/MediaRefField.hooks.d.ts +25 -0
- package/dist/seo/react/hooks/MediaRefField.hooks.js +30 -0
- package/dist/seo/react/hooks/SeoModuleTabs.d.ts +14 -0
- package/dist/seo/react/hooks/SeoModuleTabs.js +18 -0
- package/dist/seo/react/hooks/SeoPage.hooks.d.ts +69 -0
- package/dist/seo/react/hooks/SeoPage.hooks.js +37 -0
- package/dist/seo/react/hooks/SeoPorts.hooks.d.ts +19 -0
- package/dist/seo/react/hooks/SeoPorts.hooks.js +22 -0
- package/dist/seo/react/hooks/SitemapModal.hooks.d.ts +26 -0
- package/dist/seo/react/hooks/SitemapModal.hooks.js +20 -0
- package/dist/seo/react/hooks/use-entry-picker.hooks.d.ts +11 -0
- package/dist/seo/react/hooks/use-entry-picker.hooks.js +20 -0
- package/dist/seo/react/hooks/use-seo-entry-panel.hooks.d.ts +14 -0
- package/dist/seo/react/hooks/use-seo-entry-panel.hooks.js +26 -0
- package/dist/seo/react/hooks/use-seo-entry-section.hooks.d.ts +4 -0
- package/dist/seo/react/hooks/use-seo-entry-section.hooks.js +7 -0
- package/dist/seo/react/hooks/use-seo.hooks.d.ts +11 -0
- package/dist/seo/react/hooks/use-seo.hooks.js +29 -0
- package/dist/seo/react/hooks/use-sitemap-modal.hooks.d.ts +10 -0
- package/dist/seo/react/hooks/use-sitemap-modal.hooks.js +18 -0
- package/dist/seo/react/index.d.ts +369 -0
- package/dist/seo/react/index.js +30 -0
- package/dist/seo/react/options.d.ts +26 -0
- package/dist/seo/react/options.js +2 -0
- package/dist/seo/react/pages/SeoPage.d.ts +161 -0
- package/dist/seo/react/pages/SeoPage.js +215 -0
- package/dist/seo/rules.d.ts +142 -0
- package/dist/seo/rules.js +220 -0
- package/dist/seo/seo.module.d.ts +115 -0
- package/dist/seo/seo.module.js +14 -0
- package/dist/source-control/react/hooks/ProvidersTab.hooks.d.ts +1 -1
- package/dist/source-control/react/hooks/ProvidersTab.hooks.js +1 -1
- package/dist/source-control/react/hooks/SourceControlPage.hooks.d.ts +1 -1
- package/dist/source-control/react/index.js +1 -1
- package/dist/source-control/react/pages/SourceControlPage.d.ts +1 -1
- package/dist/source-control/react/tabs/ProvidersTab.d.ts +1 -1
- package/dist/widgets/adapters/http.d.ts +19 -0
- package/dist/widgets/adapters/http.js +33 -0
- package/dist/widgets/adapters/memory.d.ts +22 -0
- package/dist/widgets/adapters/memory.js +93 -0
- package/dist/widgets/conformance/widgets-api.conformance.d.ts +6 -0
- package/dist/widgets/conformance/widgets-api.conformance.js +55 -0
- package/dist/widgets/controllers/instance-editor.controller.d.ts +49 -0
- package/dist/widgets/controllers/instance-editor.controller.js +87 -0
- package/dist/widgets/controllers/library.controller.d.ts +33 -0
- package/dist/widgets/controllers/library.controller.js +53 -0
- package/dist/widgets/controllers/region-editor.controller.d.ts +42 -0
- package/dist/widgets/controllers/region-editor.controller.js +69 -0
- package/dist/widgets/controllers/regions.controller.d.ts +27 -0
- package/dist/widgets/controllers/regions.controller.js +44 -0
- package/dist/widgets/index.d.ts +11 -0
- package/dist/widgets/index.js +9 -0
- package/dist/widgets/messages.en.d.ts +78 -0
- package/dist/widgets/messages.en.js +83 -0
- package/dist/widgets/models.d.ts +62 -0
- package/dist/widgets/models.js +2 -0
- package/dist/widgets/ports.d.ts +79 -0
- package/dist/widgets/ports.js +5 -0
- package/dist/widgets/react/components/WidgetInstanceNotices.d.ts +14 -0
- package/dist/widgets/react/components/WidgetInstanceNotices.js +25 -0
- package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.d.ts +22 -0
- package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.js +18 -0
- package/dist/widgets/react/components/WidgetsLibraryNotices.d.ts +13 -0
- package/dist/widgets/react/components/WidgetsLibraryNotices.js +10 -0
- package/dist/widgets/react/hooks/WidgetsPorts.hooks.d.ts +270 -0
- package/dist/widgets/react/hooks/WidgetsPorts.hooks.js +17 -0
- package/dist/widgets/react/hooks/navigation.hooks.d.ts +9 -0
- package/dist/widgets/react/hooks/navigation.hooks.js +6 -0
- package/dist/widgets/react/hooks/page-views.hooks.d.ts +87 -0
- package/dist/widgets/react/hooks/page-views.hooks.js +30 -0
- package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.d.ts +56 -0
- package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.js +38 -0
- package/dist/widgets/react/hooks/use-widget-region-editor.hooks.d.ts +32 -0
- package/dist/widgets/react/hooks/use-widget-region-editor.hooks.js +22 -0
- package/dist/widgets/react/hooks/use-widget-regions.hooks.d.ts +23 -0
- package/dist/widgets/react/hooks/use-widget-regions.hooks.js +22 -0
- package/dist/widgets/react/hooks/use-widgets-library.hooks.d.ts +37 -0
- package/dist/widgets/react/hooks/use-widgets-library.hooks.js +23 -0
- package/dist/widgets/react/index.d.ts +391 -0
- package/dist/widgets/react/index.js +31 -0
- package/dist/widgets/react/pages/WidgetInstanceEditor.d.ts +23 -0
- package/dist/widgets/react/pages/WidgetInstanceEditor.js +37 -0
- package/dist/widgets/react/pages/WidgetRegionEditor.d.ts +22 -0
- package/dist/widgets/react/pages/WidgetRegionEditor.js +25 -0
- package/dist/widgets/react/pages/WidgetRegions.d.ts +21 -0
- package/dist/widgets/react/pages/WidgetRegions.js +31 -0
- package/dist/widgets/react/pages/WidgetsLibrary.d.ts +24 -0
- package/dist/widgets/react/pages/WidgetsLibrary.js +61 -0
- package/dist/widgets/rules.d.ts +94 -0
- package/dist/widgets/rules.js +83 -0
- package/dist/widgets/widgets.module.d.ts +122 -0
- package/dist/widgets/widgets.module.js +21 -0
- package/package.json +206 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
2
|
import { type ConfirmTone } from '../../types.js';
|
|
3
3
|
import { type UseConfirmDialog } from './ConfirmDialog.hooks.js';
|
|
4
4
|
/**
|
|
@@ -10,8 +10,8 @@ import { type UseConfirmDialog } from './ConfirmDialog.hooks.js';
|
|
|
10
10
|
* overlay + backdrop idiom: that shape hand-rolls focus trapping, Escape handling, and a backdrop
|
|
11
11
|
* element, all of which the browser's own top layer gives a real `<dialog>` for free, including
|
|
12
12
|
* correct stacking above everything else on the page without a chosen `z-index`. The `showModal`/
|
|
13
|
-
* `close` calls themselves, and the jsdom fallback they need,
|
|
14
|
-
* see that
|
|
13
|
+
* `close` calls themselves, and the jsdom fallback they need, are delegated by
|
|
14
|
+
* `ConfirmDialog.hooks.tsx` to UI-kit's native hook — see that adapter's doc comment.
|
|
15
15
|
*
|
|
16
16
|
* Unstyled, like everything in this layer: the `.confirm-dialog` / `.btn-secondary` /
|
|
17
17
|
* `.btn-danger` / `.btn-warning` class names are emitted for the host stylesheet to define.
|
|
@@ -51,7 +51,7 @@ import { type UseConfirmDialog } from './ConfirmDialog.hooks.js';
|
|
|
51
51
|
* Labels state both the action and its consequence tier, derived from this component's own
|
|
52
52
|
* three-tier `ConfirmTone` vocabulary rather than reparsed from `title`/`body`: `body` is arbitrary
|
|
53
53
|
* `ReactNode` (a caller can pass JSX), not guaranteed to be a string at all, so it cannot be safely
|
|
54
|
-
* folded into agent-facing text —
|
|
54
|
+
* folded into agent-facing text — the shared UI-kit confirmation planner owns those phrases.
|
|
55
55
|
*/
|
|
56
56
|
export interface ConfirmDialogProps {
|
|
57
57
|
open: boolean;
|
|
@@ -90,6 +90,23 @@ export interface ConfirmDialogProps {
|
|
|
90
90
|
* effect without `agentHandle`. @default true */
|
|
91
91
|
agentMayConfirm?: boolean;
|
|
92
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* UI-kit's confirmation planner owns the sub-handle segments appended to the caller's base:
|
|
95
|
+
* literals chosen by the mechanism, never host data. Neither needs sanitizing, unlike
|
|
96
|
+
* `RowMenu`'s per-item keys (see this file's "Agent handles" contract).
|
|
97
|
+
*
|
|
98
|
+
* Its plain-language consequence phrase is keyed off the dialog's three-tier `ConfirmTone`
|
|
99
|
+
* vocabulary (`"default"` / `"warning"` / `"danger"`, documented in `../../types.js`), rather
|
|
100
|
+
* than reparsed from `title` or `body`, which cannot safely supply agent-facing consequence text.
|
|
101
|
+
* The confirm label names the action (`confirmLabel`), target (`title`) and declared consequence;
|
|
102
|
+
* the planner does not parse `body` to decide whether an action is safe.
|
|
103
|
+
*
|
|
104
|
+
* The cancel label's consequence is a guarantee of the contract (cancelling never calls
|
|
105
|
+
* `onConfirm`), rather than something read off `tone`, so it needs no tone input at all.
|
|
106
|
+
* Agent attributes retain the shape used by `RowMenu`'s local `rowMenuAgentProps`; injecting
|
|
107
|
+
* admin's attribute port into the shared owner preserves that shape and handle validation
|
|
108
|
+
* without keeping a second local implementation. No base handle means no agent attributes.
|
|
109
|
+
*/
|
|
93
110
|
/**
|
|
94
111
|
* Controlled modal confirm — renders the `<dialog>` markup and delegates its open/close and focus
|
|
95
112
|
* lifecycle to {@link useConfirmDialog} (injectable via the `useDialog` prop, defaulted to the real
|
|
@@ -99,5 +116,5 @@ export interface ConfirmDialogProps {
|
|
|
99
116
|
* is no browser-assigned "default button" for Enter to reach for at all; confirm can only ever fire
|
|
100
117
|
* from an explicit click or explicit Tab-then-Enter onto it.
|
|
101
118
|
*/
|
|
102
|
-
export declare function ConfirmDialog({ useDialog, agentHandle: baseHandle, agentMayConfirm, ...props }: ConfirmDialogProps): import("react").JSX.Element;
|
|
119
|
+
export declare function ConfirmDialog({ useDialog, agentHandle: baseHandle, agentMayConfirm, ...props }: ConfirmDialogProps, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
103
120
|
//# sourceMappingURL=ConfirmDialog.d.ts.map
|
|
@@ -78,10 +78,10 @@ export declare function useConfirmDialogCancelLabel(_requiredArgs: Record<string
|
|
|
78
78
|
readonly explicit?: string | undefined;
|
|
79
79
|
}): string;
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
81
|
+
* Adapts UI-kit's `<dialog>` element open/close lifecycle and focus management for `ConfirmDialog`.
|
|
82
82
|
*
|
|
83
83
|
* The caller keeps `ConfirmDialog` mounted and toggles `open` — it is never conditionally rendered
|
|
84
|
-
* by its parent — so the
|
|
84
|
+
* by its parent — so the shared native hook has a stable `<dialog>` element to call `showModal()`/
|
|
85
85
|
* `close()` on and to restore focus through when it closes.
|
|
86
86
|
*
|
|
87
87
|
* Focus moves to the *cancel* action on open, not confirm — an operator whose first keystroke after
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext,
|
|
2
|
+
import { createContext, useContext, useMemo, useRef, } from 'react';
|
|
3
|
+
import { useNativeDialog } from '@jini-ai/ui-kit/react/native';
|
|
3
4
|
/** Empty object, not `undefined` — {@link useConfirmDialogCancelLabel} can always read `cancelLabel`
|
|
4
5
|
* off it without an extra null check, whether or not a provider is mounted. */
|
|
5
6
|
const ConfirmDialogDefaultsContext = createContext({});
|
|
@@ -41,10 +42,10 @@ export function useConfirmDialogCancelLabel(_requiredArgs, { explicit } = {}) {
|
|
|
41
42
|
return explicit ?? cancelLabel ?? DEFAULT_CANCEL_LABEL;
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
|
-
*
|
|
45
|
+
* Adapts UI-kit's `<dialog>` element open/close lifecycle and focus management for `ConfirmDialog`.
|
|
45
46
|
*
|
|
46
47
|
* The caller keeps `ConfirmDialog` mounted and toggles `open` — it is never conditionally rendered
|
|
47
|
-
* by its parent — so the
|
|
48
|
+
* by its parent — so the shared native hook has a stable `<dialog>` element to call `showModal()`/
|
|
48
49
|
* `close()` on and to restore focus through when it closes.
|
|
49
50
|
*
|
|
50
51
|
* Focus moves to the *cancel* action on open, not confirm — an operator whose first keystroke after
|
|
@@ -60,63 +61,24 @@ export function useConfirmDialog({ open, onCancel, document }, { pending } = {})
|
|
|
60
61
|
// in document order regardless of which dialog is actually open — a screen reader announcing
|
|
61
62
|
// "Delete role?" while the operator is about to confirm "Delete policy?", on a destructive
|
|
62
63
|
// action. `useId()` gives every mounted instance its own id for free.
|
|
63
|
-
const titleId = useId();
|
|
64
|
-
const dialogRef = useRef(null);
|
|
65
|
-
const cancelRef = useRef(null);
|
|
66
64
|
// Captured at the moment `open` flips true, before focus moves into the dialog — the element that
|
|
67
65
|
// had focus then is, by construction, whatever triggered this dialog (a `RowMenu` item's
|
|
68
66
|
// "Delete", a plain trigger button, …). Restored on close rather than left wherever the browser's
|
|
69
67
|
// own modal-focus algorithm happened to land (its default without this is `<body>`, which drops a
|
|
70
68
|
// keyboard user back to the top of the page).
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
cancelRef.current?.focus();
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
if (typeof dialog.close === 'function') {
|
|
89
|
-
if (dialog.open)
|
|
90
|
-
dialog.close();
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
dialog.removeAttribute('open');
|
|
94
|
-
}
|
|
95
|
-
if (triggerRef.current instanceof HTMLElement)
|
|
96
|
-
triggerRef.current.focus();
|
|
97
|
-
}
|
|
98
|
-
}, [open, document]);
|
|
99
|
-
function handleNativeCancel(e) {
|
|
100
|
-
// Fires on Escape while a real `showModal()`-opened dialog has focus. Always prevented: the
|
|
101
|
-
// effect above is the single source of truth for open/closed (driven by `open`), so
|
|
102
|
-
// letting the browser close the element on its own would desync DOM state from React state.
|
|
103
|
-
// Escape still closes the dialog — it just does so by routing through `onCancel`, same as a
|
|
104
|
-
// Cancel-button click, so the caller's `open` state (and therefore this same effect) is what
|
|
105
|
-
// actually calls `dialog.close()`.
|
|
106
|
-
e.preventDefault();
|
|
107
|
-
if (pending)
|
|
108
|
-
return;
|
|
109
|
-
onCancel();
|
|
110
|
-
}
|
|
111
|
-
function handleBackdropClick(e) {
|
|
112
|
-
// A `<dialog>` element's own box is sized to its content, not the viewport — a click that lands
|
|
113
|
-
// on the `<dialog>` element itself (as opposed to one of its children) is therefore a click on
|
|
114
|
-
// the backdrop area outside that content box.
|
|
115
|
-
if (pending)
|
|
116
|
-
return;
|
|
117
|
-
if (e.target === dialogRef.current)
|
|
118
|
-
onCancel();
|
|
119
|
-
}
|
|
69
|
+
// Fires on Escape while a real `showModal()`-opened dialog has focus. Always prevented: the
|
|
70
|
+
// shared native hook is the single source of truth for open/closed (driven by `open`), so
|
|
71
|
+
// letting the browser close the element on its own would desync DOM state from React state.
|
|
72
|
+
// Escape still closes the dialog — it just does so by routing through `onCancel`, same as a
|
|
73
|
+
// Cancel-button click, so the caller's `open` state (and therefore this same effect) is what
|
|
74
|
+
// actually calls `dialog.close()`.
|
|
75
|
+
// A `<dialog>` element's own box is sized to its content, not the viewport — a click that lands
|
|
76
|
+
// on the `<dialog>` element itself (as opposed to one of its children) is therefore a click on
|
|
77
|
+
// the backdrop area outside that content box.
|
|
78
|
+
const cancelRef = useRef(null);
|
|
79
|
+
const vm = useNativeDialog({ open, title: '', onClose: () => onCancel(), ...(pending === undefined ? {} : { pending }) }, { document, initialFocus: () => cancelRef.current?.focus() });
|
|
80
|
+
const titleId = vm.titleId, dialogRef = vm.props.ref;
|
|
81
|
+
const handleNativeCancel = vm.props.onCancel, handleBackdropClick = vm.props.onClick;
|
|
120
82
|
return { titleId, dialogRef, cancelRef, handleNativeCancel, handleBackdropClick };
|
|
121
83
|
}
|
|
122
84
|
//# sourceMappingURL=ConfirmDialog.hooks.js.map
|
|
@@ -1,72 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {} from 'react';
|
|
3
2
|
import { agentHandle } from '@jini-ai/agentic';
|
|
3
|
+
import { useConfirmController } from '@jini-ai/ui-kit/react';
|
|
4
4
|
import { resolveTone, toneClassName } from '../../types.js';
|
|
5
5
|
import { useConfirmDialog, useConfirmDialogCancelLabel } from './ConfirmDialog.hooks.js';
|
|
6
|
-
/** Sub-handle segments appended to the caller's base — literals this component chooses itself,
|
|
7
|
-
* never host data (see this file's "Agent handles" doc comment for why that means neither needs
|
|
8
|
-
* sanitizing, unlike `RowMenu`'s per-item keys). */
|
|
9
|
-
const CONFIRM_HANDLE_ACTION = 'confirm';
|
|
10
|
-
const CANCEL_HANDLE_ACTION = 'cancel';
|
|
11
6
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* why those cannot be safely folded into agent-facing text.
|
|
7
|
+
* UI-kit's confirmation planner owns the sub-handle segments appended to the caller's base:
|
|
8
|
+
* literals chosen by the mechanism, never host data. Neither needs sanitizing, unlike
|
|
9
|
+
* `RowMenu`'s per-item keys (see this file's "Agent handles" contract).
|
|
16
10
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (tone === 'danger')
|
|
23
|
-
return 'cannot be undone';
|
|
24
|
-
if (tone === 'warning')
|
|
25
|
-
return 'changes access, but is reversible';
|
|
26
|
-
return undefined;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* The confirm action's agent-facing label: what it does (`confirmLabel`), what it applies to
|
|
30
|
-
* (`title`), and — when the tone declares one — its consequence tier.
|
|
31
|
-
*
|
|
32
|
-
* @param confirmLabel - The button's own visible text, e.g. `"Delete"`.
|
|
33
|
-
* @param title - The dialog's title, e.g. `"Delete role?"`.
|
|
34
|
-
* @param tone - The dialog's resolved tone.
|
|
35
|
-
* @returns A label an agent can use to judge whether confirming is safe, without having read
|
|
36
|
-
* `body` (which this function never receives — see this file's doc comment for why).
|
|
37
|
-
* @complexity O(1).
|
|
38
|
-
*/
|
|
39
|
-
function confirmDialogConfirmLabel(confirmLabel, title, tone) {
|
|
40
|
-
const consequence = confirmDialogConsequencePhrase(tone);
|
|
41
|
-
return consequence === undefined ? `${confirmLabel} — ${title}` : `${confirmLabel} — ${title}; ${consequence}`;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* The cancel action's agent-facing label. Unlike {@link confirmDialogConfirmLabel}, its consequence
|
|
45
|
-
* is a guarantee of this component's own contract (cancelling never calls `onConfirm`) rather than
|
|
46
|
-
* something read off `tone`, so it needs no tone input at all.
|
|
47
|
-
*
|
|
48
|
-
* @param cancelLabel - The button's own visible text, already defaulted by the caller.
|
|
49
|
-
* @param title - The dialog's title, e.g. `"Delete role?"`.
|
|
50
|
-
* @returns A label stating that this action leaves the titled action unconfirmed.
|
|
51
|
-
* @complexity O(1).
|
|
52
|
-
*/
|
|
53
|
-
function confirmDialogCancelLabel(cancelLabel, title) {
|
|
54
|
-
return `${cancelLabel} — leaves "${title}" unconfirmed; no action taken`;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Builds the `data-agent-*` attribute props for one of this dialog's two actions, or nothing at
|
|
58
|
-
* all when the dialog published no base handle — same shape as `RowMenu.tsx`'s local
|
|
59
|
-
* `rowMenuAgentProps`, kept local and unexported here since only this one component needs it.
|
|
11
|
+
* Its plain-language consequence phrase is keyed off the dialog's three-tier `ConfirmTone`
|
|
12
|
+
* vocabulary (`"default"` / `"warning"` / `"danger"`, documented in `../../types.js`), rather
|
|
13
|
+
* than reparsed from `title` or `body`, which cannot safely supply agent-facing consequence text.
|
|
14
|
+
* The confirm label names the action (`confirmLabel`), target (`title`) and declared consequence;
|
|
15
|
+
* the planner does not parse `body` to decide whether an action is safe.
|
|
60
16
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
17
|
+
* The cancel label's consequence is a guarantee of the contract (cancelling never calls
|
|
18
|
+
* `onConfirm`), rather than something read off `tone`, so it needs no tone input at all.
|
|
19
|
+
* Agent attributes retain the shape used by `RowMenu`'s local `rowMenuAgentProps`; injecting
|
|
20
|
+
* admin's attribute port into the shared owner preserves that shape and handle validation
|
|
21
|
+
* without keeping a second local implementation. No base handle means no agent attributes.
|
|
66
22
|
*/
|
|
67
|
-
function confirmDialogAgentProps(base, action, options) {
|
|
68
|
-
return base === undefined ? {} : agentHandle({ handle: `${base}-${action}` }, options);
|
|
69
|
-
}
|
|
70
23
|
/**
|
|
71
24
|
* Controlled modal confirm — renders the `<dialog>` markup and delegates its open/close and focus
|
|
72
25
|
* lifecycle to {@link useConfirmDialog} (injectable via the `useDialog` prop, defaulted to the real
|
|
@@ -76,16 +29,26 @@ function confirmDialogAgentProps(base, action, options) {
|
|
|
76
29
|
* is no browser-assigned "default button" for Enter to reach for at all; confirm can only ever fire
|
|
77
30
|
* from an explicit click or explicit Tab-then-Enter onto it.
|
|
78
31
|
*/
|
|
79
|
-
export function ConfirmDialog({ useDialog = useConfirmDialog, agentHandle: baseHandle, agentMayConfirm = true, ...props }) {
|
|
80
|
-
const { titleId, dialogRef, cancelRef, handleNativeCancel, handleBackdropClick } = useDialog({ open: props.open, onCancel: props.onCancel, document }, { pending: props.pending });
|
|
32
|
+
export function ConfirmDialog({ useDialog = useConfirmDialog, agentHandle: baseHandle, agentMayConfirm = true, ...props }, _optional = {}) {
|
|
81
33
|
const tone = resolveTone({}, props);
|
|
82
34
|
const cancelLabel = useConfirmDialogCancelLabel({}, { explicit: props.cancelLabel });
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
35
|
+
const controller = useConfirmController({
|
|
36
|
+
open: props.open, title: props.title, body: props.body, confirmLabel: props.confirmLabel,
|
|
37
|
+
cancelLabel, tone, agentMayConfirm,
|
|
38
|
+
...(baseHandle === undefined ? {} : { agentHandle: baseHandle }),
|
|
39
|
+
...(props.pending === undefined ? {} : { pending: props.pending }),
|
|
40
|
+
onConfirm: () => props.onConfirm(), onCancel: () => props.onCancel(),
|
|
41
|
+
}, {
|
|
42
|
+
// UI-kit names selects separately; agentic publishes them as fields and still owns handle validation.
|
|
43
|
+
agent: ((required, optional = {}) => agentHandle(required, {
|
|
44
|
+
...(optional.role === undefined ? {} : { role: optional.role === 'select' ? 'field' : optional.role }),
|
|
45
|
+
...(optional.label === undefined ? {} : { label: optional.label }),
|
|
46
|
+
})),
|
|
47
|
+
});
|
|
48
|
+
const { titleId, dialogRef, cancelRef, handleNativeCancel, handleBackdropClick } = useDialog({ open: props.open, onCancel: () => { controller.requestDismiss({ reason: 'close' }); }, document }, { pending: controller.pending });
|
|
49
|
+
// Keep admin's concise accessible names; the shared planner still supplies consequence-aware agent labels.
|
|
50
|
+
const { 'aria-label': _cancelName, ...cancelAttrs } = controller.cancel.attrs ?? {};
|
|
51
|
+
const { 'aria-label': _confirmName, ...confirmAttrs } = controller.confirm.attrs ?? {};
|
|
52
|
+
return (_jsxs("dialog", { ref: dialogRef, className: "confirm-dialog", "aria-labelledby": titleId, onCancel: handleNativeCancel, onClick: handleBackdropClick, children: [_jsx("h2", { id: titleId, children: props.title }), _jsxs("div", { className: "confirm-dialog-body", children: [props.body, controller.error] }), _jsxs("div", { className: "confirm-dialog-actions", children: [_jsx("button", { ref: cancelRef, type: "button", className: "btn-secondary", disabled: controller.pending, onClick: () => controller.cancel.onPress?.({}), ...cancelAttrs, children: cancelLabel }), _jsx("button", { type: "button", className: toneClassName({ tone }), disabled: controller.pending, onClick: () => controller.confirm.onPress?.({}), ...confirmAttrs, children: props.confirmLabel })] })] }));
|
|
90
53
|
}
|
|
91
54
|
//# sourceMappingURL=ConfirmDialog.js.map
|
|
@@ -12,13 +12,14 @@ const VIEWPORT_MARGIN = 8;
|
|
|
12
12
|
* visible jump. Recomputed on scroll and resize too: a portaled menu is a DOM sibling of its anchor,
|
|
13
13
|
* not a child, so it does not track the anchor's position on its own the way an in-flow popup would.
|
|
14
14
|
*
|
|
15
|
-
* Click-outside
|
|
15
|
+
* Click-outside and Escape close. Escape is document-scoped so it also works after focus
|
|
16
|
+
* moves away from the popup. Scoped to the open window only, same lifecycle discipline as
|
|
16
17
|
* `ConfirmButton`'s armed-only document listeners — a closed, idle `RowMenu` costs nothing beyond
|
|
17
18
|
* its trigger button even with many mounted per table.
|
|
18
19
|
*
|
|
19
20
|
* @complexity O(1) per call and per scroll/resize/mousedown event.
|
|
20
21
|
*/
|
|
21
|
-
function trackOpenMenu({ trigger, menu }, { window, document, onPosition, onDismiss }) {
|
|
22
|
+
function trackOpenMenu({ trigger, menu }, { window, document, onPosition, onDismiss, onEscape }) {
|
|
22
23
|
function reposition() {
|
|
23
24
|
const rect = trigger.getBoundingClientRect();
|
|
24
25
|
const menuHeight = menu.offsetHeight;
|
|
@@ -41,14 +42,23 @@ function trackOpenMenu({ trigger, menu }, { window, document, onPosition, onDism
|
|
|
41
42
|
return;
|
|
42
43
|
onDismiss();
|
|
43
44
|
}
|
|
45
|
+
function onDocKeyDown(e) {
|
|
46
|
+
if (e.key !== 'Escape' || e.defaultPrevented)
|
|
47
|
+
return;
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
e.stopPropagation();
|
|
50
|
+
onEscape();
|
|
51
|
+
}
|
|
44
52
|
reposition();
|
|
45
53
|
window.addEventListener('scroll', reposition, true);
|
|
46
54
|
window.addEventListener('resize', reposition);
|
|
47
55
|
document.addEventListener('mousedown', onDocMouseDown);
|
|
56
|
+
document.addEventListener('keydown', onDocKeyDown);
|
|
48
57
|
return () => {
|
|
49
58
|
window.removeEventListener('scroll', reposition, true);
|
|
50
59
|
window.removeEventListener('resize', reposition);
|
|
51
60
|
document.removeEventListener('mousedown', onDocMouseDown);
|
|
61
|
+
document.removeEventListener('keydown', onDocKeyDown);
|
|
52
62
|
};
|
|
53
63
|
}
|
|
54
64
|
/**
|
|
@@ -89,7 +99,7 @@ export function useRowMenu({ itemCount, window, document }) {
|
|
|
89
99
|
let stop;
|
|
90
100
|
return (menu) => {
|
|
91
101
|
if (menu)
|
|
92
|
-
stop = trackOpenMenu({ trigger: anchor, menu }, { window, document, onPosition: setPosition, onDismiss: () => close(false) });
|
|
102
|
+
stop = trackOpenMenu({ trigger: anchor, menu }, { window, document, onPosition: setPosition, onDismiss: () => close(false), onEscape: () => close(true) });
|
|
93
103
|
else
|
|
94
104
|
stop();
|
|
95
105
|
};
|
|
@@ -140,6 +150,7 @@ export function useRowMenu({ itemCount, window, document }) {
|
|
|
140
150
|
break;
|
|
141
151
|
case 'Escape':
|
|
142
152
|
e.preventDefault();
|
|
153
|
+
e.stopPropagation();
|
|
143
154
|
close(true);
|
|
144
155
|
break;
|
|
145
156
|
case 'Tab':
|
|
@@ -1,16 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import type { ControllerStore } from '../core/module/controller-store.js';
|
|
3
|
-
/** Factory runs after commit, never during render. Each effect attachment owns a fresh
|
|
4
|
-
* controller, so StrictMode's cleanup/replay cannot revive a disposed controller. */
|
|
5
|
-
export declare function useController<C extends ControllerStore<unknown>>({ create, dependencies }: {
|
|
6
|
-
create: () => C;
|
|
7
|
-
dependencies: DependencyList;
|
|
8
|
-
}, { start, }?: {
|
|
9
|
-
start?: (required: {
|
|
10
|
-
controller: C;
|
|
11
|
-
}, optional?: Record<string, never>) => void;
|
|
12
|
-
}): {
|
|
13
|
-
controller: C | null;
|
|
14
|
-
snapshot: ReturnType<C["getSnapshot"]> | null;
|
|
15
|
-
};
|
|
1
|
+
export * from '../core/react/use-controller.js';
|
|
16
2
|
//# sourceMappingURL=use-controller.d.ts.map
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* controller, so StrictMode's cleanup/replay cannot revive a disposed controller. */
|
|
4
|
-
export function useController({ create, dependencies }, { start, } = {}) {
|
|
5
|
-
const [controller, setController] = useState(null);
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
const current = create();
|
|
8
|
-
setController(current);
|
|
9
|
-
start?.({ controller: current });
|
|
10
|
-
return () => current.dispose();
|
|
11
|
-
// Dependencies are explicitly supplied by the owning hook, like useMemo's contract.
|
|
12
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
13
|
-
}, dependencies);
|
|
14
|
-
const subscribe = useCallback((listener) => controller?.subscribe({ listener }) ?? (() => { }), [controller]);
|
|
15
|
-
const snapshot = useSyncExternalStore(subscribe, () => (controller?.getSnapshot() ?? null), () => null);
|
|
16
|
-
return { controller, snapshot };
|
|
17
|
-
}
|
|
1
|
+
// Compatibility path; the shared implementation lives in core.
|
|
2
|
+
export * from '../core/react/use-controller.js';
|
|
18
3
|
//# sourceMappingURL=use-controller.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AdminRedirectsPort } from '../../core/ports/redirects.js';
|
|
2
|
+
/** Host owns authentication, addressing, retries and error decoding, as in media's adapter. */
|
|
3
|
+
export interface RedirectsTransportPort {
|
|
4
|
+
request<T>(required: {
|
|
5
|
+
path: string;
|
|
6
|
+
method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
7
|
+
body?: unknown;
|
|
8
|
+
}, optional?: Record<string, never>): Promise<T>;
|
|
9
|
+
url(required: {
|
|
10
|
+
path: string;
|
|
11
|
+
}, optional?: Record<string, never>): string;
|
|
12
|
+
}
|
|
13
|
+
/** Map existing HTTP envelopes to the core API without validating or rewriting operator inputs.
|
|
14
|
+
* @example createHttpRedirectsApi({ transport, basePath: workspacePath + '/redirects' }, {});
|
|
15
|
+
*/
|
|
16
|
+
export declare function createHttpRedirectsApi({ transport, basePath }: {
|
|
17
|
+
transport: RedirectsTransportPort;
|
|
18
|
+
basePath: string;
|
|
19
|
+
}, _optional?: Record<string, never>): AdminRedirectsPort;
|
|
20
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Map existing HTTP envelopes to the core API without validating or rewriting operator inputs.
|
|
2
|
+
* @example createHttpRedirectsApi({ transport, basePath: workspacePath + '/redirects' }, {});
|
|
3
|
+
*/
|
|
4
|
+
export function createHttpRedirectsApi({ transport, basePath }, _optional = {}) {
|
|
5
|
+
const base = basePath.replace(/\/$/, '');
|
|
6
|
+
const path = (id) => `${base}/${encodeURIComponent(id)}`;
|
|
7
|
+
async function record(method, target, body) {
|
|
8
|
+
const response = await transport.request({ path: target, method, ...(body === undefined ? {} : { body }) });
|
|
9
|
+
return response.data;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
async listRedirects(_required, filter = {}) {
|
|
13
|
+
const query = new URLSearchParams();
|
|
14
|
+
for (const key of ['status', 'source', 'matchType']) {
|
|
15
|
+
if (filter[key] !== undefined)
|
|
16
|
+
query.set(key, filter[key]);
|
|
17
|
+
}
|
|
18
|
+
const suffix = query.size ? `?${query.toString()}` : '';
|
|
19
|
+
return (await transport.request({ path: `${base}${suffix}`, method: 'GET' })).data;
|
|
20
|
+
},
|
|
21
|
+
getRedirect: ({ id }) => record('GET', path(id)),
|
|
22
|
+
createRedirect: (input, options = {}) => record('POST', base, { ...input, ...options }),
|
|
23
|
+
updateRedirect: ({ id }, patch = {}) => record('PATCH', path(id), patch),
|
|
24
|
+
tombstoneRedirect: ({ id }) => record('DELETE', path(id)),
|
|
25
|
+
async getRedirectHitStats({ id }) {
|
|
26
|
+
return (await transport.request({ path: `${path(id)}/hits`, method: 'GET' })).data;
|
|
27
|
+
},
|
|
28
|
+
importRedirects: ({ rules }) => transport.request({ path: `${base}/import`, method: 'POST', body: { rules } }),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AdminRedirect, AdminRedirectCreateInput, AdminRedirectHitStats, AdminRedirectImportResult, AdminRedirectsPort } from '../../core/ports/redirects.js';
|
|
2
|
+
/** Presentation backend, not a routing engine: host validators/origin policy remain server owned.
|
|
3
|
+
* Optional validation lets a host model its own open match vocabulary without a second schema.
|
|
4
|
+
* @example createMemoryRedirectsApi({ redirects: [] }, {});
|
|
5
|
+
*/
|
|
6
|
+
export declare function createMemoryRedirectsApi({ redirects, hits }: {
|
|
7
|
+
redirects?: readonly AdminRedirect[];
|
|
8
|
+
hits?: Readonly<Record<string, AdminRedirectHitStats>>;
|
|
9
|
+
}, { validate, onImport }?: {
|
|
10
|
+
validate?: (input: AdminRedirectCreateInput) => void;
|
|
11
|
+
onImport?: (rules: readonly AdminRedirectCreateInput[]) => AdminRedirectImportResult | undefined;
|
|
12
|
+
}): AdminRedirectsPort;
|
|
13
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { AdminApiError } from '../../core/transport/errors.js';
|
|
2
|
+
/** Presentation backend, not a routing engine: host validators/origin policy remain server owned.
|
|
3
|
+
* Optional validation lets a host model its own open match vocabulary without a second schema.
|
|
4
|
+
* @example createMemoryRedirectsApi({ redirects: [] }, {});
|
|
5
|
+
*/
|
|
6
|
+
export function createMemoryRedirectsApi({ redirects = [], hits = {} }, { validate, onImport } = {}) {
|
|
7
|
+
const rows = new Map(redirects.map(row => [row.id, Object.freeze({ ...row })]));
|
|
8
|
+
const stats = new Map(Object.entries(hits).map(([id, value]) => [id, Object.freeze({ ...value })]));
|
|
9
|
+
let nextId = 1;
|
|
10
|
+
function get(id) {
|
|
11
|
+
const row = rows.get(id);
|
|
12
|
+
if (!row)
|
|
13
|
+
throw new AdminApiError({ message: `redirect '${id}' was not found`, status: 404 }, { code: 'REDIRECT_NOT_FOUND' });
|
|
14
|
+
return row;
|
|
15
|
+
}
|
|
16
|
+
function create(input, source) {
|
|
17
|
+
// The core port documents reference-host rejection. A supplied validator owns alternate hosts.
|
|
18
|
+
if (validate)
|
|
19
|
+
validate(input);
|
|
20
|
+
else if (input.matchType === 'regex')
|
|
21
|
+
throw new AdminApiError({ message: 'regex match type is not supported', status: 400 }, { code: 'REDIRECT_VALIDATION_ERROR' });
|
|
22
|
+
let id;
|
|
23
|
+
do {
|
|
24
|
+
id = `memory-redirect-${nextId++}`;
|
|
25
|
+
} while (rows.has(id));
|
|
26
|
+
const row = Object.freeze({ ...input, id, status: 'active', override: input.override ?? false,
|
|
27
|
+
priority: input.priority ?? 0, source, sourceEntryId: null, fromPathAtCapture: null, toPathAtCapture: null,
|
|
28
|
+
createdByPrincipal: 'memory-principal', createdByPluginId: null,
|
|
29
|
+
createdAt: new Date(0).toISOString(), updatedAt: new Date(0).toISOString(), version: 1 });
|
|
30
|
+
rows.set(id, row);
|
|
31
|
+
return row;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
async listRedirects(_required, filter = {}) {
|
|
35
|
+
return Object.freeze([...rows.values()].filter(row => (filter.status === undefined || row.status === filter.status) &&
|
|
36
|
+
(filter.source === undefined || row.source === filter.source) &&
|
|
37
|
+
(filter.matchType === undefined || row.matchType === filter.matchType)));
|
|
38
|
+
},
|
|
39
|
+
async getRedirect({ id }) { return get(id); },
|
|
40
|
+
async createRedirect(input, options = {}) { return create({ ...input, ...options }, 'manual'); },
|
|
41
|
+
async updateRedirect({ id }, patch = {}) {
|
|
42
|
+
const before = get(id);
|
|
43
|
+
const next = { ...before, ...patch };
|
|
44
|
+
if (validate)
|
|
45
|
+
validate(next);
|
|
46
|
+
else if (patch.matchType === 'regex')
|
|
47
|
+
throw new AdminApiError({ message: 'regex match type is not supported', status: 400 }, { code: 'REDIRECT_VALIDATION_ERROR' });
|
|
48
|
+
const row = Object.freeze({ ...next, version: before.version + 1 });
|
|
49
|
+
rows.set(id, row);
|
|
50
|
+
return row;
|
|
51
|
+
},
|
|
52
|
+
async tombstoneRedirect({ id }) {
|
|
53
|
+
const row = get(id);
|
|
54
|
+
if (row.status === 'disabled')
|
|
55
|
+
return row;
|
|
56
|
+
const disabled = Object.freeze({ ...row, status: 'disabled', version: row.version + 1 });
|
|
57
|
+
rows.set(id, disabled);
|
|
58
|
+
return disabled;
|
|
59
|
+
},
|
|
60
|
+
async getRedirectHitStats({ id }) {
|
|
61
|
+
get(id);
|
|
62
|
+
return stats.get(id) ?? Object.freeze({ redirectId: id, hitCount: 0, lastHitAt: null });
|
|
63
|
+
},
|
|
64
|
+
async importRedirects({ rules }) {
|
|
65
|
+
const overridden = onImport?.(rules);
|
|
66
|
+
if (overridden)
|
|
67
|
+
return overridden;
|
|
68
|
+
const created = [], failed = [];
|
|
69
|
+
// One failed item never discards successful siblings; no per-item network I/O.
|
|
70
|
+
for (const [index, input] of rules.entries()) {
|
|
71
|
+
try {
|
|
72
|
+
created.push(create(input, 'import'));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
failed.push({ index, code: error instanceof AdminApiError ? error.code ?? 'INTERNAL_ERROR' : 'INTERNAL_ERROR',
|
|
76
|
+
message: error instanceof AdminApiError ? error.message : 'an internal error occurred' });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { created: Object.freeze(created), failed: Object.freeze(failed) };
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AdminRedirectsPort } from '../../core/ports/redirects.js';
|
|
2
|
+
/** Destructive framework-free checklist: use an isolated backend with no production data.
|
|
3
|
+
* Validates core soft-delete, snapshots, lazy-read data and per-item partial import contracts.
|
|
4
|
+
* Reference regex rejection probes can be disabled for a host implementing the port's open vocabulary.
|
|
5
|
+
* @example await runRedirectsApiConformance({ api: createMemoryRedirectsApi({}, {}) }, {});
|
|
6
|
+
*/
|
|
7
|
+
export declare function runRedirectsApiConformance({ api }: {
|
|
8
|
+
api: AdminRedirectsPort;
|
|
9
|
+
}, { referenceRegexRejection }?: {
|
|
10
|
+
referenceRegexRejection?: boolean;
|
|
11
|
+
}): Promise<readonly string[]>;
|
|
12
|
+
//# sourceMappingURL=redirects-api.conformance.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AdminApiError } from '../../core/transport/errors.js';
|
|
2
|
+
/** Destructive framework-free checklist: use an isolated backend with no production data.
|
|
3
|
+
* Validates core soft-delete, snapshots, lazy-read data and per-item partial import contracts.
|
|
4
|
+
* Reference regex rejection probes can be disabled for a host implementing the port's open vocabulary.
|
|
5
|
+
* @example await runRedirectsApiConformance({ api: createMemoryRedirectsApi({}, {}) }, {});
|
|
6
|
+
*/
|
|
7
|
+
export async function runRedirectsApiConformance({ api }, { referenceRegexRejection = true } = {}) {
|
|
8
|
+
const checks = [];
|
|
9
|
+
function assert(ok, name) {
|
|
10
|
+
if (!ok)
|
|
11
|
+
throw new AdminApiError({ message: `Redirects API conformance: ${name}`, status: 0 }, { code: 'CONFORMANCE_FAILED' });
|
|
12
|
+
checks.push(name);
|
|
13
|
+
}
|
|
14
|
+
async function rejects(run, name) {
|
|
15
|
+
let rejected = false;
|
|
16
|
+
try {
|
|
17
|
+
await run();
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
rejected = true;
|
|
21
|
+
}
|
|
22
|
+
assert(rejected, name);
|
|
23
|
+
}
|
|
24
|
+
const input = { matchType: 'exact', fromPattern: '/redirects-conformance-a', toTarget: '/redirects-conformance-b', statusCode: 301 };
|
|
25
|
+
const created = await api.createRedirect(input, { override: true, priority: 7 });
|
|
26
|
+
assert(created.status === 'active' && created.override && created.priority === 7, 'create preserves fields and options');
|
|
27
|
+
const before = await api.listRedirects({});
|
|
28
|
+
assert(before.some(row => row.id === created.id), 'list contains the created rule');
|
|
29
|
+
assert((await api.getRedirect({ id: created.id })).id === created.id, 'get reads by id');
|
|
30
|
+
const hits = await api.getRedirectHitStats({ id: created.id });
|
|
31
|
+
assert(hits.redirectId === created.id && hits.hitCount === 0 && hits.lastHitAt === null, 'new rule has zero hits');
|
|
32
|
+
const updated = await api.updateRedirect({ id: created.id }, { status: 'disabled' });
|
|
33
|
+
assert(updated.status === 'disabled' && updated.toTarget === created.toTarget, 'partial update preserves other fields');
|
|
34
|
+
assert(created.status === 'active' && before.find(row => row.id === created.id)?.status === 'active', 'prior snapshots stay unchanged');
|
|
35
|
+
assert((await api.listRedirects({}, { status: 'disabled' })).every(row => row.status === 'disabled'), 'status filter');
|
|
36
|
+
await api.updateRedirect({ id: created.id }, { status: 'active' });
|
|
37
|
+
const disabled = await api.tombstoneRedirect({ id: created.id });
|
|
38
|
+
assert(disabled.status === 'disabled', 'tombstone returns the disabled rule');
|
|
39
|
+
assert((await api.listRedirects({})).some(row => row.id === created.id), 'soft deletion retains the rule');
|
|
40
|
+
assert((await api.getRedirect({ id: created.id })).status === 'disabled', 'tombstoned rule remains readable');
|
|
41
|
+
await rejects(() => api.getRedirect({ id: 'missing-conformance-rule' }), 'missing rule rejects');
|
|
42
|
+
await rejects(() => api.getRedirectHitStats({ id: 'missing-conformance-rule' }), 'missing hits differs from zero hits');
|
|
43
|
+
await rejects(() => api.updateRedirect({ id: 'missing-conformance-rule' }, { status: 'disabled' }), 'missing update rejects');
|
|
44
|
+
await rejects(() => api.tombstoneRedirect({ id: 'missing-conformance-rule' }), 'missing tombstone rejects');
|
|
45
|
+
if (referenceRegexRejection) {
|
|
46
|
+
await rejects(() => api.createRedirect({ ...input, fromPattern: '/regex-conformance', matchType: 'regex' }), 'reference regex create is loudly rejected');
|
|
47
|
+
await rejects(() => api.updateRedirect({ id: created.id }, { matchType: 'regex' }), 'reference regex update is loudly rejected');
|
|
48
|
+
}
|
|
49
|
+
const batch = await api.importRedirects({ rules: [
|
|
50
|
+
{ ...input, fromPattern: '/import-conformance-a' },
|
|
51
|
+
...(referenceRegexRejection ? [{ ...input, fromPattern: '/import-conformance-regex', matchType: 'regex' }] : []),
|
|
52
|
+
{ ...input, fromPattern: '/import-conformance-c' },
|
|
53
|
+
] });
|
|
54
|
+
if (referenceRegexRejection) {
|
|
55
|
+
assert(batch.created.length === 2 && batch.failed.length === 1 && batch.failed[0]?.index === 1, 'middle failure preserves both successful siblings');
|
|
56
|
+
assert(batch.created.every(row => row.fromPattern !== '/import-conformance-regex'), 'invalid item is never reported created');
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
assert(batch.created.length === 2 && batch.failed.length === 0, 'valid import batch succeeds');
|
|
60
|
+
}
|
|
61
|
+
assert(batch.created.every(row => row.source === 'import'), 'import provenance is stamped by the backend');
|
|
62
|
+
for (const row of batch.created)
|
|
63
|
+
await api.tombstoneRedirect({ id: row.id });
|
|
64
|
+
return Object.freeze(checks);
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=redirects-api.conformance.js.map
|