@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
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import type { AdminSeoSettings, AdminSeoSettingsPatch, AdminSeoMeta, AdminSeoAnalysis, AdminSeoOverridesPatch, AdminSeoEntryChoice } from '../core/ports/seo.js';
|
|
2
|
+
import type { MediaAsset } from '../contracts/media-picker.js';
|
|
3
|
+
import type { SitemapUrlEntry } from './rules.js';
|
|
4
|
+
export type SeoSettings = AdminSeoSettings;
|
|
5
|
+
export type SeoSettingsPatch = AdminSeoSettingsPatch;
|
|
6
|
+
export type SeoEntryMeta = AdminSeoMeta;
|
|
7
|
+
export type SeoEntryAnalysis = AdminSeoAnalysis;
|
|
8
|
+
export type SeoEntryOverridesPatch = AdminSeoOverridesPatch;
|
|
9
|
+
export type SeoIssue = import('../core/ports/seo.js').AdminSeoIssue;
|
|
10
|
+
/** Extra host fields survive picker reads; only id/title/status participate in rendering. */
|
|
11
|
+
export type AdminPost = AdminSeoEntryChoice & {
|
|
12
|
+
readonly workspaceId?: string;
|
|
13
|
+
readonly kind?: string;
|
|
14
|
+
readonly slug?: string;
|
|
15
|
+
readonly bodyJson?: unknown;
|
|
16
|
+
readonly updatedAt?: string;
|
|
17
|
+
readonly version?: number;
|
|
18
|
+
};
|
|
19
|
+
/** The existing picker returns its media row unchanged; slug is an optional projection. */
|
|
20
|
+
export interface SeoMediaSelection extends MediaAsset {
|
|
21
|
+
readonly slug?: string;
|
|
22
|
+
readonly workspaceId?: string;
|
|
23
|
+
readonly caption?: string;
|
|
24
|
+
readonly credit?: string;
|
|
25
|
+
readonly sha256?: string;
|
|
26
|
+
readonly status?: string;
|
|
27
|
+
readonly createdAt?: string;
|
|
28
|
+
readonly updatedAt?: string;
|
|
29
|
+
readonly version?: number;
|
|
30
|
+
readonly width?: number | null;
|
|
31
|
+
readonly height?: number | null;
|
|
32
|
+
readonly cssClass?: string | null;
|
|
33
|
+
readonly htmlAttributes?: string | null;
|
|
34
|
+
}
|
|
35
|
+
export type AdminMedia = SeoMediaSelection;
|
|
36
|
+
export type SeoTranslator = (key: string, vars?: Record<string, string | number>) => string;
|
|
37
|
+
/** Host API error classes remain host-owned; format their empty-message semantics at the seam. */
|
|
38
|
+
export type SeoErrorFormatter = (required: {
|
|
39
|
+
error: unknown;
|
|
40
|
+
fallback: string;
|
|
41
|
+
}, optional?: Record<string, never>) => string;
|
|
42
|
+
export interface SeoController {
|
|
43
|
+
settings: SeoSettings | null;
|
|
44
|
+
error: string | null;
|
|
45
|
+
saving: boolean;
|
|
46
|
+
notice: string | null;
|
|
47
|
+
/** Takes a `SeoSettingsPatch` rather than a `Partial<SeoSettings>` so an emptied optional field
|
|
48
|
+
* can send `null` and actually clear its site default — `setSeoSettings` is a merge, so an
|
|
49
|
+
* omitted key means "unchanged" (see the core port's `AdminSeoSettingsPatch`). */
|
|
50
|
+
save: (patch: SeoSettingsPatch) => Promise<void>;
|
|
51
|
+
/** The site-wide default OG/Twitter image field's own controlled value (MediaRefField picker
|
|
52
|
+
* support, 2026-09-05) — every OTHER default on this screen stays an uncontrolled `defaultValue`
|
|
53
|
+
* (read via `FormData` on submit, `react/pages/SeoPage.tsx`'s own file header), but a picker needs somewhere to
|
|
54
|
+
* WRITE a selection into, which an uncontrolled input has no seam for. Re-synced from `settings`
|
|
55
|
+
* whenever it (re)loads — including after a successful save, so the field reflects what was
|
|
56
|
+
* actually persisted rather than the operator's last unsaved edit. `""` until settings load. */
|
|
57
|
+
defaultOgImage: string;
|
|
58
|
+
setDefaultOgImage: (value: string) => void;
|
|
59
|
+
/** Resolves `true` on success, `false` on a caught failure (`error` is set either way this
|
|
60
|
+
* already did) — `SitemapModal.tsx`'s own footer Regenerate button uses the boolean to decide
|
|
61
|
+
* whether to refetch `/sitemap.xml`, so a failed attempt never re-fetches the same stale
|
|
62
|
+
* content. The pre-existing caller, `react/pages/SeoPage.tsx`'s own Regenerate button, still just fires this as
|
|
63
|
+
* a plain `onClick` and discards the return value — this is a widening, not a breaking change. */
|
|
64
|
+
regenerateSitemap: () => Promise<boolean>;
|
|
65
|
+
/** Whether `SitemapModal.tsx` ("View sitemap") is open. `react/pages/SeoPage.tsx` stays markup-only (this file's
|
|
66
|
+
* own header) by keeping this state here alongside the rest of the screen's state, the same way
|
|
67
|
+
* `SeoEntrySection`'s own `entryId` selection lives in `useSeoEntrySection` rather than in
|
|
68
|
+
* `react/pages/SeoPage.tsx` itself. */
|
|
69
|
+
sitemapModalOpen: boolean;
|
|
70
|
+
openSitemapModal: () => void;
|
|
71
|
+
closeSitemapModal: () => void;
|
|
72
|
+
/** Legacy component metadata retained for the copied render contract. Translation is always
|
|
73
|
+
* taken from the injected module t function, never from a package-owned locale dictionary. */
|
|
74
|
+
locale: string;
|
|
75
|
+
}
|
|
76
|
+
export interface EntryPickerController {
|
|
77
|
+
entries: readonly AdminPost[] | null;
|
|
78
|
+
error: string | null;
|
|
79
|
+
}
|
|
80
|
+
export interface SeoEntryPanelOptions {
|
|
81
|
+
entryId: string;
|
|
82
|
+
}
|
|
83
|
+
export interface SeoEntryPanelController {
|
|
84
|
+
resolved: SeoEntryMeta | null;
|
|
85
|
+
analysis: SeoEntryAnalysis | null;
|
|
86
|
+
loadError: string | null;
|
|
87
|
+
saving: boolean;
|
|
88
|
+
saveError: string | null;
|
|
89
|
+
notice: string | null;
|
|
90
|
+
/** Reads back whatever the operator touched for `key`, falling back to the resolved
|
|
91
|
+
* (server-effective) value for any field not yet edited this session. A field the operator
|
|
92
|
+
* EMPTIED reads back as `null` (the pending clear), which `react/pages/SeoPage.tsx`'s own `?? ""` renders as an
|
|
93
|
+
* empty box — so the field the operator cleared stays cleared on screen. */
|
|
94
|
+
fieldValue: <K extends keyof SeoEntryOverridesPatch>(key: K, resolvedValue: SeoEntryOverridesPatch[K]) => SeoEntryOverridesPatch[K];
|
|
95
|
+
setField: <K extends keyof SeoEntryOverridesPatch>(key: K, value: SeoEntryOverridesPatch[K]) => void;
|
|
96
|
+
save: () => Promise<void>;
|
|
97
|
+
/** The patch `save` will PUT — only the fields the operator actually touched this session, with
|
|
98
|
+
* `null` for each one they emptied. An untouched field is ABSENT, never `null`: "unchanged" must
|
|
99
|
+
* never become "clear". */
|
|
100
|
+
touched: SeoEntryOverridesPatch;
|
|
101
|
+
}
|
|
102
|
+
export interface SeoEntrySectionController {
|
|
103
|
+
entryId: string;
|
|
104
|
+
setEntryId: (entryId: string) => void;
|
|
105
|
+
}
|
|
106
|
+
export type SitemapModalView = "table" | "raw";
|
|
107
|
+
/** `"disabled"` is a real, terminal state, not a stalled `"loading"`: with `sitemapEnabled` false the
|
|
108
|
+
* modal deliberately never fetches, so there is nothing in flight to be loading. Naming it keeps
|
|
109
|
+
* `SitemapModal.tsx`'s header honest — `sitemapModalTitle`/`SitemapModalHeaderActions` both key off
|
|
110
|
+
* `status === "ready"`, so a URL count and the raw/table toggle stay off a sitemap that is off. */
|
|
111
|
+
export type SitemapModalStatus = "disabled" | "loading" | "error" | "ready";
|
|
112
|
+
/** What {@link useSitemapModal} needs from its caller. An object rather than trailing positional
|
|
113
|
+
* parameters specifically so the `SitemapModal.tsx` `useModal` test seam forwards it whole: a
|
|
114
|
+
* positional `enabled` can be silently dropped by a shorter test double (TypeScript accepts a
|
|
115
|
+
* function of fewer parameters), which is exactly how the "this never fetches" claim below went
|
|
116
|
+
* untested while the fetch fired on every open. */
|
|
117
|
+
export interface SitemapModalInputs {
|
|
118
|
+
/** `settings.sitemapEnabled` — when `false`, `/sitemap.xml` is never requested at all. */
|
|
119
|
+
enabled: boolean;
|
|
120
|
+
/** Retained for the existing hook ABI; SitemapModal forwards close directly to Jini. */
|
|
121
|
+
onClose: () => void;
|
|
122
|
+
}
|
|
123
|
+
/** What {@link useSitemapModal} (and {@link useWiredSitemapModal}) hands back to
|
|
124
|
+
* `SitemapModal.tsx` — the modal's full render-time contract. */
|
|
125
|
+
export interface SitemapModalController {
|
|
126
|
+
status: SitemapModalStatus;
|
|
127
|
+
/** A describable failure message, set only while `status === "error"`. */
|
|
128
|
+
error: string | null;
|
|
129
|
+
/** The exact response text from `GET /sitemap.xml`, set only while `status === "ready"`. */
|
|
130
|
+
xmlText: string;
|
|
131
|
+
/** Every parsed `<url>` entry, unfiltered — `SitemapModal.tsx`'s header URL count reads this. */
|
|
132
|
+
entries: SitemapUrlEntry[];
|
|
133
|
+
/** `entries` narrowed by {@link filter}. */
|
|
134
|
+
filteredEntries: SitemapUrlEntry[];
|
|
135
|
+
filter: string;
|
|
136
|
+
setFilter: (value: string) => void;
|
|
137
|
+
view: SitemapModalView;
|
|
138
|
+
setView: (view: SitemapModalView) => void;
|
|
139
|
+
/** Re-runs the fetch — `SitemapModal.tsx`'s footer Regenerate button calls this after a
|
|
140
|
+
* successful regenerate, so the count/table/raw view all reflect the freshly rebuilt sitemap
|
|
141
|
+
* without the operator closing and reopening the modal. */
|
|
142
|
+
refetch: () => void;
|
|
143
|
+
}
|
|
144
|
+
export interface MediaRefFieldController {
|
|
145
|
+
/** Whether `MediaPickerDialog` is open. */
|
|
146
|
+
pickerOpen: boolean;
|
|
147
|
+
openPicker: () => void;
|
|
148
|
+
closePicker: () => void;
|
|
149
|
+
/** `MediaPickerDialog`'s `onSelect` — writes the exact `{slug}:public` ref
|
|
150
|
+
* (`buildMediaRef`, `rules.ts`, readable-slugs S5b) into the field and closes the dialog. */
|
|
151
|
+
handleSelect: (item: SeoMediaSelection) => void;
|
|
152
|
+
/** Clears the field to `""` — an OG image must be removable (SPEC intent). */
|
|
153
|
+
clear: () => void;
|
|
154
|
+
/** The field's current value resolved to a thumbnail `<img src>`, or `null` when the value is
|
|
155
|
+
* empty or unparseable — see `resolveMediaRefPreviewUrl`'s own doc. */
|
|
156
|
+
previewUrl: string | null;
|
|
157
|
+
/** `MediaPickerDialog`'s `accept` — images only: every field this backs is an og:image /
|
|
158
|
+
* twitter:image, and a crawler cannot use a video there (2026-10-05, same filter the post
|
|
159
|
+
* featured-image chooser passes). */
|
|
160
|
+
accept: readonly string[];
|
|
161
|
+
}
|
|
162
|
+
export type SeoState = Omit<SeoController, 'save' | 'setDefaultOgImage' | 'regenerateSitemap' | 'openSitemapModal' | 'closeSitemapModal' | 'locale'>;
|
|
163
|
+
export type SeoEntryState = Pick<SeoEntryPanelController, 'resolved' | 'analysis' | 'loadError' | 'saving' | 'saveError' | 'notice' | 'touched'>;
|
|
164
|
+
export interface SitemapState {
|
|
165
|
+
status: SitemapModalStatus;
|
|
166
|
+
error: string | null;
|
|
167
|
+
xmlText: string;
|
|
168
|
+
filter: string;
|
|
169
|
+
view: SitemapModalView;
|
|
170
|
+
}
|
|
171
|
+
export declare const initialSeoState: SeoState;
|
|
172
|
+
export declare const initialSeoEntryState: SeoEntryState;
|
|
173
|
+
export declare const initialEntryPickerState: EntryPickerController;
|
|
174
|
+
/** Error messages remain visible; the host transport owns decoding its API errors. */
|
|
175
|
+
export declare function describeSeoError({ error, fallback }: {
|
|
176
|
+
error: unknown;
|
|
177
|
+
fallback: string;
|
|
178
|
+
}, _optional?: Record<string, never>): string;
|
|
179
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const initialSeoState = { settings: null, error: null, saving: false, notice: null, defaultOgImage: '', sitemapModalOpen: false };
|
|
2
|
+
export const initialSeoEntryState = { resolved: null, analysis: null, loadError: null, saving: false, saveError: null, notice: null, touched: {} };
|
|
3
|
+
export const initialEntryPickerState = { entries: null, error: null };
|
|
4
|
+
/** Error messages remain visible; the host transport owns decoding its API errors. */
|
|
5
|
+
export function describeSeoError({ error, fallback }, _optional = {}) {
|
|
6
|
+
return error instanceof Error ? error.message : fallback;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AdminSeoPort } from '../core/ports/seo.js';
|
|
2
|
+
export type { AdminSeoPort } from '../core/ports/seo.js';
|
|
3
|
+
export declare const seoApiToken: import("../core/module/token.js").AdminPortToken<AdminSeoPort, "admin.seo.api">;
|
|
4
|
+
/** A host event invalidates this scope's settings; it carries no unauthorized rows. */
|
|
5
|
+
export interface SeoEventsPort {
|
|
6
|
+
subscribe(required: {
|
|
7
|
+
onRefresh: () => void;
|
|
8
|
+
}, optional?: Record<string, never>): () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const seoEventsToken: import("../core/module/token.js").AdminPortToken<SeoEventsPort, "admin.seo.events">;
|
|
11
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SeoMediaPickerSlotProps } from '../options.js';
|
|
2
|
+
/** The shared picker service owns its UI; this consumer never renders a second picker. */
|
|
3
|
+
export declare function MediaPickerBridge(props: SeoMediaPickerSlotProps, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
4
|
+
//# sourceMappingURL=MediaPickerBridge.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMediaPickerBridge } from '../hooks/MediaPickerBridge.hooks.js';
|
|
3
|
+
/** The shared picker service owns its UI; this consumer never renders a second picker. */
|
|
4
|
+
export function MediaPickerBridge(props, _optional = {}) {
|
|
5
|
+
const { error, cancel } = useMediaPickerBridge(props);
|
|
6
|
+
return _jsx(_Fragment, { children: error && _jsxs("div", { role: "alert", children: [error, _jsx("button", { type: "button", onClick: cancel, children: "Cancel" })] }) });
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=MediaPickerBridge.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useWiredMediaRefField } from "../hooks/MediaRefField.hooks.js";
|
|
2
|
+
/**
|
|
3
|
+
* @file `MediaRefField` — a text input for an `{assetId}:{transformName}` media reference (or a
|
|
4
|
+
* pasted absolute URL), plus a "Choose image" affordance that opens the existing
|
|
5
|
+
* `MediaPickerDialog`, a thumbnail preview of the current value, and a Remove control.
|
|
6
|
+
*
|
|
7
|
+
* Built for `react/pages/SeoPage.tsx`'s `defaultOgImage`/`ogImage`/`twitterImage` fields (SPEC intent: "make the OG
|
|
8
|
+
* image selectable, with a preview") — the text input keeps working unchanged (an addition, not a
|
|
9
|
+
* replacement: anyone scripting or pasting a raw ref/URL still can), the picker is the new path.
|
|
10
|
+
*
|
|
11
|
+
* State — the dialog's open/closed flag, the selection handler, and the preview URL — lives in
|
|
12
|
+
* `react/hooks/MediaRefField.hooks.ts`, split out the same way `MediaPickerDialog`/`MediaPickerDialog.hooks
|
|
13
|
+
* .tsx` does; this file stays props-and-JSX only. `MediaPickerDialog` itself is reused unchanged
|
|
14
|
+
* (`components/MediaPickerDialog/MediaPickerDialog.tsx`) — no fork, no new picker UI.
|
|
15
|
+
*
|
|
16
|
+
* 2026-10-08 polish: the original editable-input rationale above still applies to pasted URLs
|
|
17
|
+
* and empty fields. A selected library reference now shows plain copy with its preview; Remove
|
|
18
|
+
* returns to manual entry. A hidden input preserves the exact FormData value on defaults saves.
|
|
19
|
+
*/
|
|
20
|
+
export interface MediaRefFieldProps {
|
|
21
|
+
locale: string;
|
|
22
|
+
/** `<input id>`/`<label htmlFor>` pairing — same `getByLabelText`-friendly shape `react/pages/SeoPage.tsx`'s
|
|
23
|
+
* other explicit-`htmlFor` fields already use. */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Forwarded to the `<input name>` only when set — `defaultOgImage` needs this (its `<form>` reads
|
|
26
|
+
* `FormData` by name on submit); the per-entry `ogImage`/`twitterImage` fields do not (they save
|
|
27
|
+
* through `fieldValue`/`setField`, never `FormData`), so it stays optional. */
|
|
28
|
+
name?: string;
|
|
29
|
+
label: string;
|
|
30
|
+
value: string;
|
|
31
|
+
onChange: (value: string) => void;
|
|
32
|
+
/** This field's own base handle — appended `-choose`/`-clear`/`-dialog` for its own controls, and
|
|
33
|
+
* forwarded as-is to the `<input>` itself. Omit to leave every element here untagged. */
|
|
34
|
+
agentHandle?: string;
|
|
35
|
+
/** Injectable seam for the picker's own state — same convention as `MediaPickerDialog`'s own
|
|
36
|
+
* `useDialog` prop. Defaults to the real {@link useWiredMediaRefField}. */
|
|
37
|
+
useField?: typeof useWiredMediaRefField;
|
|
38
|
+
}
|
|
39
|
+
export declare function MediaRefField({ locale, id, name, label, value, onChange, agentHandle: base, useField, }: MediaRefFieldProps, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
40
|
+
//# sourceMappingURL=MediaRefField.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { agentHandle } from "@jini-ai/agentic";
|
|
3
|
+
import { MediaPickerBridge } from "./MediaPickerBridge.js";
|
|
4
|
+
import { useSeoCopy } from "../hooks/SeoPorts.hooks.js";
|
|
5
|
+
import { useWiredMediaRefField, useMediaRefPresentation, handleSpread } from "../hooks/MediaRefField.hooks.js";
|
|
6
|
+
export function MediaRefField({ locale, id, name, label, value, onChange, agentHandle: base, useField = useWiredMediaRefField, }, _optional = {}) {
|
|
7
|
+
const t = useSeoCopy();
|
|
8
|
+
const { Picker = MediaPickerBridge, storedReference } = useMediaRefPresentation({ value });
|
|
9
|
+
const { pickerOpen, openPicker, closePicker, handleSelect, clear, previewUrl, accept } = useField({ value, onChange });
|
|
10
|
+
return (_jsxs("div", { className: "jini-field jini-media-ref-field", children: [_jsx("label", { className: "jini-field-label", htmlFor: id, children: label }), _jsxs("div", { className: "jini-media-ref-field-row", children: [_jsx("input", { className: "jini-input", id: id, name: storedReference ? undefined : name, value: storedReference ? t({ locale, key: "Selected image" }) : value, readOnly: storedReference, onChange: (e) => onChange(e.target.value), ...(base ? agentHandle({ handle: base }, { role: "field", label }) : {}) }), storedReference && name ? _jsx("input", { type: "hidden", name: name, value: value }) : null, _jsx("button", { type: "button", className: "jini-btn jini-btn-secondary", onClick: openPicker, ...handleSpread({ ...(base === undefined ? {} : { base }), suffix: "choose", label: `Choose an image for: ${label}` }), children: t({ locale: locale, key: "Choose image" }) }), value ? (_jsx("button", { type: "button", className: "jini-btn jini-btn-secondary", onClick: clear, ...handleSpread({ ...(base === undefined ? {} : { base }), suffix: "clear", label: `Remove the selected image for: ${label}` }), children: t({ locale: locale, key: "Remove" }) })) : null] }), previewUrl ? _jsx("img", { className: "jini-media-ref-field-preview", src: previewUrl, alt: `${label} preview` }) : null, pickerOpen ? (_jsx(Picker, { onSelect: handleSelect, onCancel: closePicker, accept: accept, agentHandle: base ? `${base}-dialog` : undefined })) : null] }));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=MediaRefField.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Site defaults — sliders, i.e. values that are set once and then apply to everything. */
|
|
2
|
+
export declare function SeoDefaultsIcon({ size }: {
|
|
3
|
+
size?: number;
|
|
4
|
+
}, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
5
|
+
/** Sitemap — a node branching into children, i.e. the shape of the file this tab rebuilds. */
|
|
6
|
+
export declare function SeoSitemapIcon({ size }: {
|
|
7
|
+
size?: number;
|
|
8
|
+
}, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
9
|
+
/** Pages & posts — stacked documents, i.e. the collection this tab edits one at a time. */
|
|
10
|
+
export declare function SeoEntriesIcon({ size }: {
|
|
11
|
+
size?: number;
|
|
12
|
+
}, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=SeoIcons.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/** Shared attributes for a decorative line icon — copied deliberately from
|
|
3
|
+
* `deployment-visuals.tsx`'s own `LINE_ICON` so this tab row reads as the same family as the
|
|
4
|
+
* Deployment tab row it was modelled on (24px grid, 1.5 stroke, round joins). Local rather than
|
|
5
|
+
* imported across the feature boundary: `features/deployment/index.ts` is that feature's public
|
|
6
|
+
* surface and does not export it, and this app ships no shared icon module — the sidebar's glyphs
|
|
7
|
+
* in `App.tsx` and `SettingsUi.tsx`'s tab icons are both inline SVG for the same reason.
|
|
8
|
+
* `aria-hidden` on every one: each sits directly beside the text label that already says the same
|
|
9
|
+
* thing (`frontend-accessibility` — do not give an accessible name to decoration that duplicates
|
|
10
|
+
* adjacent visible text). */
|
|
11
|
+
const LINE_ICON = {
|
|
12
|
+
viewBox: "0 0 24 24",
|
|
13
|
+
fill: "none",
|
|
14
|
+
stroke: "currentColor",
|
|
15
|
+
strokeWidth: 1.5,
|
|
16
|
+
strokeLinecap: "round",
|
|
17
|
+
strokeLinejoin: "round",
|
|
18
|
+
"aria-hidden": true,
|
|
19
|
+
};
|
|
20
|
+
/** Site defaults — sliders, i.e. values that are set once and then apply to everything. */
|
|
21
|
+
export function SeoDefaultsIcon({ size = 16 }, _optional = {}) {
|
|
22
|
+
return (_jsxs("svg", { ...LINE_ICON, width: size, height: size, children: [_jsx("path", { d: "M4 6h10M18 6h2M4 12h2M10 12h10M4 18h8M16 18h4" }), _jsx("circle", { cx: "16", cy: "6", r: "2" }), _jsx("circle", { cx: "8", cy: "12", r: "2" }), _jsx("circle", { cx: "14", cy: "18", r: "2" })] }));
|
|
23
|
+
}
|
|
24
|
+
/** Sitemap — a node branching into children, i.e. the shape of the file this tab rebuilds. */
|
|
25
|
+
export function SeoSitemapIcon({ size = 16 }, _optional = {}) {
|
|
26
|
+
return (_jsxs("svg", { ...LINE_ICON, width: size, height: size, children: [_jsx("rect", { x: "9", y: "3", width: "6", height: "4", rx: "1" }), _jsx("rect", { x: "3", y: "17", width: "6", height: "4", rx: "1" }), _jsx("rect", { x: "15", y: "17", width: "6", height: "4", rx: "1" }), _jsx("path", { d: "M12 7v4M6 17v-2h12v2M12 11v4" })] }));
|
|
27
|
+
}
|
|
28
|
+
/** Pages & posts — stacked documents, i.e. the collection this tab edits one at a time. */
|
|
29
|
+
export function SeoEntriesIcon({ size = 16 }, _optional = {}) {
|
|
30
|
+
return (_jsxs("svg", { ...LINE_ICON, width: size, height: size, children: [_jsx("path", { d: "M8 3h6l4 4v10a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z" }), _jsx("path", { d: "M14 3v4h4" }), _jsx("path", { d: "M10 12h5M10 16h3" })] }));
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=SeoIcons.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useWiredSitemapModal } from "../hooks/use-sitemap-modal.hooks.js";
|
|
2
|
+
/**
|
|
3
|
+
* `SitemapModal` — "View sitemap" (owner request, `react/pages/SeoPage.tsx`'s Sitemap card). Reads the exact same
|
|
4
|
+
* `GET /sitemap.xml` bytes a crawler gets (`sitemap-dependencies.hooks.ts`'s `defaultSitemapPort`,
|
|
5
|
+
* via `siteUrl()`) and renders them as a filterable `URL | Last modified` table, with a Raw XML
|
|
6
|
+
* toggle for verifying the literal response text. `changefreq`/`priority` columns were considered
|
|
7
|
+
* and dropped: `server/inbound/public-http/routes/site/sitemap.ts` never emits either field (read
|
|
8
|
+
* directly, not guessed), so a column for them would only ever show blank.
|
|
9
|
+
*
|
|
10
|
+
* Jini's Dialog owns modality and focus confinement: aria-modal promises the background cannot
|
|
11
|
+
* be reached with Tab. `.sitemap-modal` widens the shared chrome to about 900px; its body is the
|
|
12
|
+
* single scrolling region between fixed header and footer.
|
|
13
|
+
*
|
|
14
|
+
* Domain state (fetch, parse, filter, view toggle) lives in `hooks/use-sitemap-modal
|
|
15
|
+
* .hooks.ts`; this file is markup only — the one bit of sequencing that belongs to neither that
|
|
16
|
+
* hook nor the outer `useSeo()` (refetching after a successful regenerate) lives in its own
|
|
17
|
+
* colocated `react/hooks/SitemapModal.hooks.ts`, see that file's header for why it isn't folded into either.
|
|
18
|
+
*
|
|
19
|
+
* ## Agent handles
|
|
20
|
+
* Every interactive element carries its own `agentHandle` (grep `agentHandle(` in `react/pages/SeoPage.tsx` for
|
|
21
|
+
* the convention this follows): the raw-XML link, the table/raw toggle, the filter box, each row's
|
|
22
|
+
* URL link (namespaced via `buildAgentListHandles`, the same per-item scheme `MediaPickerDialog
|
|
23
|
+
* .tsx` uses), the footer Regenerate button, and the footer Close button.
|
|
24
|
+
*/
|
|
25
|
+
export interface SitemapModalProps {
|
|
26
|
+
locale: string;
|
|
27
|
+
/** `settings.sitemapEnabled` from `useSeo()` — when `false`, the modal shows why instead of a
|
|
28
|
+
* table (REQ 8: "disabled" and "on but zero URLs" are different facts, so this never fetches to
|
|
29
|
+
* find out — it already knows).
|
|
30
|
+
*
|
|
31
|
+
* Threaded into `useSitemapModal` as `SitemapModalInputs.enabled` so the fetch, header and Raw XML
|
|
32
|
+
* toggle all agree with the disabled body. */
|
|
33
|
+
sitemapEnabled: boolean;
|
|
34
|
+
/** `saving` from `useSeo()` — shared with the outer page's own Save/Regenerate buttons, same as
|
|
35
|
+
* today's single-flag convention (`react/pages/SeoPage.tsx`'s existing `disabled={saving}` on both). */
|
|
36
|
+
regenerating: boolean;
|
|
37
|
+
/** `regenerateSitemap` from `useSeo()`. Resolves `true` on success, `false` on a caught failure —
|
|
38
|
+
* `handleRegenerate` below only refetches on `true`, matching REQ 7 ("after a SUCCESSFUL
|
|
39
|
+
* regenerate it refetches"). */
|
|
40
|
+
onRegenerate: () => Promise<boolean>;
|
|
41
|
+
onClose: () => void;
|
|
42
|
+
/** Injectable seam for the modal's fetch/parse/filter/view state. Defaults to the real
|
|
43
|
+
* {@link useWiredSitemapModal}; a test can pass a fake here to exercise this component's
|
|
44
|
+
* rendering against a fixed `SitemapModalController`. */
|
|
45
|
+
useModal?: typeof useWiredSitemapModal;
|
|
46
|
+
}
|
|
47
|
+
export declare function SitemapModal({ locale, sitemapEnabled, regenerating, onRegenerate, onClose, useModal, }: SitemapModalProps, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
48
|
+
//# sourceMappingURL=SitemapModal.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { agentHandle } from "@jini-ai/agentic";
|
|
3
|
+
import { Dialog } from "@jini-ai/ui-kit/react";
|
|
4
|
+
import { formatTimestamp } from "@jini-ai/ui/panel-kit";
|
|
5
|
+
import { useSeoCopy, useSeoOptions } from "../hooks/SeoPorts.hooks.js";
|
|
6
|
+
import { actionLabel } from "../../rules.js";
|
|
7
|
+
import { useWiredSitemapModal } from "../hooks/use-sitemap-modal.hooks.js";
|
|
8
|
+
import { useSitemapModalRegenerate, useSitemapPresentation, useSitemapTable, useSitemapViewToggle } from "../hooks/SitemapModal.hooks.js";
|
|
9
|
+
/** The header's raw-XML link + table/raw toggle — only shown once there is a real response to
|
|
10
|
+
* point at (REQ 3/6). Its own component purely so {@link SitemapModal} stays a flat sequence of
|
|
11
|
+
* blocks.
|
|
12
|
+
*
|
|
13
|
+
* @complexity O(1). */
|
|
14
|
+
function SitemapModalHeaderActions({ locale, modal }) {
|
|
15
|
+
const { sourceUrl } = useSitemapPresentation({ locale, modal });
|
|
16
|
+
const { toggleView } = useSitemapViewToggle({ modal });
|
|
17
|
+
const t = useSeoCopy();
|
|
18
|
+
return (_jsxs("div", { className: "sitemap-modal-header-actions", children: [_jsx("a", { className: "sitemap-modal-source-link", href: sourceUrl, target: "_blank", rel: "noreferrer", ...agentHandle({ handle: "seo-sitemap-open-raw-link" }, {
|
|
19
|
+
role: "link",
|
|
20
|
+
label: "Open the real sitemap.xml file in a new tab",
|
|
21
|
+
}), children: t({ locale: locale, key: "sitemap.xml ↗" }) }), modal.status === "ready" ? (_jsx("button", { type: "button", className: "btn-secondary", "aria-pressed": modal.view === "raw", onClick: toggleView, ...agentHandle({ handle: "seo-sitemap-raw-toggle" }, {
|
|
22
|
+
role: "button",
|
|
23
|
+
label: "Toggle between the parsed table and the raw XML response",
|
|
24
|
+
}), children: modal.view === "raw" ? t({ locale: locale, key: "Table" }) : t({ locale: locale, key: "Raw XML" }) })) : null] }));
|
|
25
|
+
}
|
|
26
|
+
/** The parsed-table view: filter box + `URL | Last modified` table, or the empty-filter/empty-
|
|
27
|
+
* sitemap notices in place of a table with nothing to show. Its own component for the same
|
|
28
|
+
* flat-sequence-of-blocks reason as {@link SitemapModalHeaderActions}.
|
|
29
|
+
*
|
|
30
|
+
* @complexity O(1) to render — `entries`/`filteredEntries` are already computed by
|
|
31
|
+
* `useSitemapModal` (memoized there), this only maps them to JSX. */
|
|
32
|
+
function SitemapModalTable({ locale, modal }) {
|
|
33
|
+
const t = useSeoCopy();
|
|
34
|
+
const { formatDate = formatTimestamp } = useSeoOptions();
|
|
35
|
+
const { rowHandles } = useSitemapTable({ modal });
|
|
36
|
+
if (modal.entries.length === 0)
|
|
37
|
+
return _jsx("div", { className: "notice", children: t({ locale: locale, key: "The sitemap has no URLs yet." }) });
|
|
38
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { type: "search", className: "sitemap-modal-filter", "aria-label": t({ locale: locale, key: "Filter sitemap URLs" }), placeholder: t({ locale: locale, key: "Filter by URL…" }), value: modal.filter, onChange: (e) => modal.setFilter(e.target.value), ...agentHandle({ handle: "seo-sitemap-filter" }, {
|
|
39
|
+
role: "field",
|
|
40
|
+
label: "Narrow the sitemap table by a substring match on the URL",
|
|
41
|
+
}) }), modal.filteredEntries.length === 0 ? (_jsx("p", { className: "muted-cell", children: t({ locale: locale, key: "No URLs match this filter." }) })) : (_jsx("div", { className: "table-scroll", children: _jsxs("table", { className: "list-table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t({ locale: locale, key: "URL" }) }), _jsx("th", { children: t({ locale: locale, key: "Last modified" }) })] }) }), _jsx("tbody", { children: modal.filteredEntries.map((entry, index) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx("a", { href: entry.loc, target: "_blank", rel: "noreferrer", ...agentHandle({ handle: rowHandles[index] }, { role: "link", label: "Open this URL on the live site" }), children: entry.loc }) }), _jsx("td", { children: entry.lastmod === null ? _jsx("span", { className: "muted-cell", children: t({ locale: locale, key: "—" }) }) : formatDate({ iso: entry.lastmod }) })] }, entry.loc))) })] }) }))] }));
|
|
42
|
+
}
|
|
43
|
+
/** The body's content-status switch (REQ 8/9: disabled, loading, error, then raw-vs-table) — kept
|
|
44
|
+
* as its own flat sequence of guards rather than a nested ternary inline in {@link SitemapModal}.
|
|
45
|
+
*
|
|
46
|
+
* @complexity O(1) — delegates the actual list rendering to {@link SitemapModalTable}. */
|
|
47
|
+
function SitemapModalBody({ locale, sitemapEnabled, modal, }) {
|
|
48
|
+
const t = useSeoCopy();
|
|
49
|
+
if (!sitemapEnabled) {
|
|
50
|
+
return (_jsx("div", { className: "notice", children: t({ locale: locale, key: 'Sitemap is off. Turn on "Sitemap enabled" above to publish one.' }) }));
|
|
51
|
+
}
|
|
52
|
+
if (modal.status === "loading")
|
|
53
|
+
return _jsx("div", { className: "notice", children: t({ locale: locale, key: "Loading sitemap…" }) });
|
|
54
|
+
if (modal.status === "error") {
|
|
55
|
+
return (_jsx("div", { className: "notice error", role: "alert", children: modal.error }));
|
|
56
|
+
}
|
|
57
|
+
if (modal.view === "raw")
|
|
58
|
+
return _jsx("pre", { className: "sitemap-modal-raw", children: modal.xmlText });
|
|
59
|
+
return _jsx(SitemapModalTable, { locale: locale, modal: modal });
|
|
60
|
+
}
|
|
61
|
+
export function SitemapModal({ locale, sitemapEnabled, regenerating, onRegenerate, onClose, useModal = useWiredSitemapModal, }, _optional = {}) {
|
|
62
|
+
const t = useSeoCopy();
|
|
63
|
+
const modal = useModal({ enabled: sitemapEnabled, onClose });
|
|
64
|
+
const { title } = useSitemapPresentation({ locale, modal });
|
|
65
|
+
const { handleRegenerate } = useSitemapModalRegenerate({ onRegenerate, refetch: modal.refetch });
|
|
66
|
+
// Native modality keeps Tab from reaching the background, as MediaPickerDialog now does too.
|
|
67
|
+
return (_jsxs(Dialog, { open: true, title: title, onClose: () => onClose(), className: "settings-dialog tovu-domain-dialog sitemap-modal", children: [_jsx("div", { className: "sitemap-modal-header", children: _jsx(SitemapModalHeaderActions, { locale: locale, modal: modal }) }), _jsx("div", { className: "sitemap-modal-body", children: _jsx(SitemapModalBody, { locale: locale, sitemapEnabled: sitemapEnabled, modal: modal }) }), _jsx("div", { className: "widget-picker-footer", children: _jsxs("span", { className: "editor-actions", children: [_jsx("button", { type: "button", className: "btn-secondary", onClick: handleRegenerate, disabled: regenerating, ...agentHandle({ handle: "seo-sitemap-modal-regenerate" }, {
|
|
68
|
+
role: "button",
|
|
69
|
+
label: "Rebuild the cached sitemap and refresh this view",
|
|
70
|
+
}), children: actionLabel({ pending: regenerating, pendingLabel: t({ locale: locale, key: "Working…" }), idleLabel: t({ locale: locale, key: "Regenerate sitemap" }) }) }), _jsx("button", { type: "button", className: "btn-secondary", onClick: onClose, "data-jini-autofocus": "", ...agentHandle({ handle: "seo-sitemap-modal-close" }, { role: "button", label: "Close the sitemap viewer" }), children: t({ locale: locale, key: "Close" }) })] }) })] }));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=SitemapModal.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SeoMediaPickerSlotProps } from '../options.js';
|
|
2
|
+
export declare function useMediaPickerBridge(required: SeoMediaPickerSlotProps, _optional?: Record<string, never>): {
|
|
3
|
+
error: string | null;
|
|
4
|
+
cancel: () => void;
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=MediaPickerBridge.hooks.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useSeoPorts } from './SeoPorts.hooks.js';
|
|
3
|
+
export function useMediaPickerBridge(required, _optional = {}) {
|
|
4
|
+
const { mediaPicker } = useSeoPorts();
|
|
5
|
+
const callbacks = useRef(required);
|
|
6
|
+
callbacks.current = required;
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!mediaPicker) {
|
|
10
|
+
setError('Media picker unavailable');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const abort = new AbortController();
|
|
14
|
+
void mediaPicker.pick({ accept: callbacks.current.accept ?? ['image/*'] }, { signal: abort.signal }).then(item => {
|
|
15
|
+
if (abort.signal.aborted)
|
|
16
|
+
return;
|
|
17
|
+
if (item)
|
|
18
|
+
callbacks.current.onSelect(item);
|
|
19
|
+
else
|
|
20
|
+
callbacks.current.onCancel();
|
|
21
|
+
}).catch(error => { if (!abort.signal.aborted)
|
|
22
|
+
setError(error instanceof Error ? error.message : 'Media picker unavailable'); });
|
|
23
|
+
return () => abort.abort();
|
|
24
|
+
}, [mediaPicker]);
|
|
25
|
+
return { error, cancel: () => callbacks.current.onCancel() };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=MediaPickerBridge.hooks.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MediaRefFieldController } from '../../models.js';
|
|
2
|
+
import type { AdminSeoPort } from '../../ports.js';
|
|
3
|
+
export type { MediaRefFieldController } from '../../models.js';
|
|
4
|
+
export declare function useMediaRefField({ value, onChange, api }: {
|
|
5
|
+
value: string;
|
|
6
|
+
onChange: (value: string) => void;
|
|
7
|
+
api: AdminSeoPort;
|
|
8
|
+
}, _optional?: Record<string, never>): MediaRefFieldController;
|
|
9
|
+
export declare function useWiredMediaRefField({ value, onChange }: {
|
|
10
|
+
value: string;
|
|
11
|
+
onChange: (value: string) => void;
|
|
12
|
+
}, _optional?: Record<string, never>): MediaRefFieldController;
|
|
13
|
+
/** Slot or existing promise picker; no picker implementation is forked into SEO. */
|
|
14
|
+
export declare function useMediaRefPresentation({ value }: {
|
|
15
|
+
value: string;
|
|
16
|
+
}, _optional?: Record<string, never>): {
|
|
17
|
+
Picker: import("react").ComponentType<import("../options.js").SeoMediaPickerSlotProps> | undefined;
|
|
18
|
+
storedReference: boolean;
|
|
19
|
+
};
|
|
20
|
+
export declare function handleSpread({ base, suffix, label }: {
|
|
21
|
+
base?: string;
|
|
22
|
+
suffix: string;
|
|
23
|
+
label: string;
|
|
24
|
+
}, _optional?: Record<string, never>): Record<string, unknown>;
|
|
25
|
+
//# sourceMappingURL=MediaRefField.hooks.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
3
|
+
import { useController } from '../../../core/react/use-controller.js';
|
|
4
|
+
import { createMediaRefController } from '../../controllers/media-ref.controller.js';
|
|
5
|
+
import { isStoredMediaRef, resolveMediaRefPreviewUrl } from '../../rules.js';
|
|
6
|
+
import { useSeoPorts, useSeoOptions } from './SeoPorts.hooks.js';
|
|
7
|
+
export function useMediaRefField({ value, onChange, api }, _optional = {}) {
|
|
8
|
+
const change = useRef(onChange);
|
|
9
|
+
change.current = onChange;
|
|
10
|
+
const { controller, snapshot } = useController({ create: () => createMediaRefController({ onChange: value => change.current(value) }), dependencies: [] });
|
|
11
|
+
return {
|
|
12
|
+
pickerOpen: snapshot?.pickerOpen ?? false,
|
|
13
|
+
openPicker: () => controller?.openPicker({}), closePicker: () => controller?.closePicker({}),
|
|
14
|
+
handleSelect: item => controller?.handleSelect({ item }), clear: () => controller?.clear({}),
|
|
15
|
+
previewUrl: resolveMediaRefPreviewUrl({ value, mediaOriginalUrl: id => api.mediaOriginalUrl({ id }) }), accept: ['image/*'],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function useWiredMediaRefField({ value, onChange }, _optional = {}) {
|
|
19
|
+
const { seoApi: api } = useSeoPorts();
|
|
20
|
+
return useMediaRefField({ value, onChange, api });
|
|
21
|
+
}
|
|
22
|
+
/** Slot or existing promise picker; no picker implementation is forked into SEO. */
|
|
23
|
+
export function useMediaRefPresentation({ value }, _optional = {}) {
|
|
24
|
+
const { slots } = useSeoOptions();
|
|
25
|
+
return { Picker: slots?.MediaPickerDialog, storedReference: isStoredMediaRef({ value }) };
|
|
26
|
+
}
|
|
27
|
+
export function handleSpread({ base, suffix, label }, _optional = {}) {
|
|
28
|
+
return base ? agentHandle({ handle: `${base}-${suffix}` }, { role: 'button', label }) : {};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=MediaRefField.hooks.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TabViewProps } from '../../../core/react/bind-react.js';
|
|
2
|
+
import type { SeoTabController } from './SeoPage.hooks.js';
|
|
3
|
+
export declare function SeoDefaultsModuleTab(_required: TabViewProps, _optional?: Record<string, never>): import("react").DetailedReactHTMLElement<{
|
|
4
|
+
className: string;
|
|
5
|
+
}, HTMLElement> | import("react").ReactElement<{
|
|
6
|
+
controller: SeoTabController;
|
|
7
|
+
}, string | import("react").JSXElementConstructor<any>>;
|
|
8
|
+
export declare function SeoSitemapModuleTab(_required: TabViewProps, _optional?: Record<string, never>): import("react").DetailedReactHTMLElement<{
|
|
9
|
+
className: string;
|
|
10
|
+
}, HTMLElement> | import("react").ReactElement<{
|
|
11
|
+
controller: SeoTabController;
|
|
12
|
+
}, string | import("react").JSXElementConstructor<any>>;
|
|
13
|
+
export declare function SeoEntriesModuleTab(_required: TabViewProps, _optional?: Record<string, never>): import("react").FunctionComponentElement<import("../pages/SeoPage.js").SeoEntrySectionProps>;
|
|
14
|
+
//# sourceMappingURL=SeoModuleTabs.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
import { SeoDefaultsTab, SeoSitemapTab, SeoEntrySection } from '../pages/SeoPage.js';
|
|
3
|
+
import { useWiredSeo } from './use-seo.hooks.js';
|
|
4
|
+
import { useSeoCopy } from './SeoPorts.hooks.js';
|
|
5
|
+
/** Standalone lazy tab mounts share the same controllers and markup as the page-owned panels. */
|
|
6
|
+
function useSettingsTab({ Panel }) {
|
|
7
|
+
const controller = useWiredSeo();
|
|
8
|
+
const t = useSeoCopy();
|
|
9
|
+
if (controller.error && !controller.settings)
|
|
10
|
+
return createElement('div', { className: 'notice error' }, controller.error);
|
|
11
|
+
if (!controller.settings)
|
|
12
|
+
return createElement('div', { className: 'notice' }, t({ key: 'Loading SEO settings…' }));
|
|
13
|
+
return createElement(Panel, { controller: { ...controller, settings: controller.settings } });
|
|
14
|
+
}
|
|
15
|
+
export function SeoDefaultsModuleTab(_required, _optional = {}) { return useSettingsTab({ Panel: SeoDefaultsTab }); }
|
|
16
|
+
export function SeoSitemapModuleTab(_required, _optional = {}) { return useSettingsTab({ Panel: SeoSitemapTab }); }
|
|
17
|
+
export function SeoEntriesModuleTab(_required, _optional = {}) { return createElement(SeoEntrySection, { locale: 'en' }); }
|
|
18
|
+
//# sourceMappingURL=SeoModuleTabs.js.map
|