@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,164 @@
|
|
|
1
|
+
import { createControllerStore } from '../../core/module/controller-store.js';
|
|
2
|
+
import { hasPermission } from '../../core/permissions/rules.js';
|
|
3
|
+
import { describeApiError } from '../../core/transport/errors.js';
|
|
4
|
+
import { describeModerationError, emptyRowState } from '../rules.js';
|
|
5
|
+
import { englishComments } from '../messages.en.js';
|
|
6
|
+
/** Headless cursor accumulation and per-row actions; page one remains owned by fetch-query.
|
|
7
|
+
* Permissions are affordances, denied by default. Every server write must reauthorize.
|
|
8
|
+
* @param required The core API and current session grants.
|
|
9
|
+
* @param optional Translator and an invalidation callback for every cached status.
|
|
10
|
+
* @returns An instance-scoped store and actions; dispose makes pending settlements inert.
|
|
11
|
+
*/
|
|
12
|
+
export function createCommentQueueController({ api, permissions = [] }, { t = englishComments, onInvalidate } = {}) {
|
|
13
|
+
const store = createControllerStore({ initial: {
|
|
14
|
+
status: 'pending', items: null, nextCursor: null, error: null, loadingMore: false,
|
|
15
|
+
rowState: {}, pendingPurge: null,
|
|
16
|
+
} });
|
|
17
|
+
let firstPage = null;
|
|
18
|
+
let morePages = [];
|
|
19
|
+
let firstError = null;
|
|
20
|
+
let moreError = null;
|
|
21
|
+
let pageGeneration = 0;
|
|
22
|
+
let loadingMore = false;
|
|
23
|
+
// Synchronous checked-then-set lock: React's busy render cannot block two same-tick actions.
|
|
24
|
+
// Different actions on the same row share this lock; different rows remain independent.
|
|
25
|
+
const busyRowIds = new Set();
|
|
26
|
+
function publishPages() {
|
|
27
|
+
store.set({ patch: {
|
|
28
|
+
items: firstPage ? [...firstPage.items, ...morePages] : null,
|
|
29
|
+
error: moreError ?? (firstError ? describeApiError({ e: firstError, fallback: t('failed to load the moderation queue') }) : null),
|
|
30
|
+
} });
|
|
31
|
+
}
|
|
32
|
+
// Accumulated pages belong to the current first page. A status switch or refreshed page one
|
|
33
|
+
// supersedes an in-flight cursor read AND releases its synchronous lock, avoiding stuck busy.
|
|
34
|
+
function resetMorePages() {
|
|
35
|
+
pageGeneration++;
|
|
36
|
+
loadingMore = false;
|
|
37
|
+
morePages = [];
|
|
38
|
+
moreError = null;
|
|
39
|
+
store.set({ patch: { loadingMore: false } });
|
|
40
|
+
}
|
|
41
|
+
function patchRowState(id, patch) {
|
|
42
|
+
const current = store.getSnapshot().rowState;
|
|
43
|
+
store.set({ patch: { rowState: { ...current, [id]: { ...emptyRowState(), ...current[id], ...patch } } } });
|
|
44
|
+
}
|
|
45
|
+
function reloadAfterAction() {
|
|
46
|
+
resetMorePages();
|
|
47
|
+
publishPages();
|
|
48
|
+
// An action moves a row to another status. Invalidating only the current filter would leave
|
|
49
|
+
// previously visited status caches stale, so the hook invalidates KEYS.queueRoot.
|
|
50
|
+
onInvalidate?.();
|
|
51
|
+
}
|
|
52
|
+
function stateFor({ id }, _optional = {}) {
|
|
53
|
+
return store.getSnapshot().rowState[id] ?? emptyRowState();
|
|
54
|
+
}
|
|
55
|
+
/** Locale/grant changes update affordances without losing the existing cursor or row state. */
|
|
56
|
+
function configure({ permissions: nextPermissions, t: nextTranslator }, _optional = {}) {
|
|
57
|
+
if (store.signal.aborted)
|
|
58
|
+
return;
|
|
59
|
+
permissions = nextPermissions;
|
|
60
|
+
t = nextTranslator;
|
|
61
|
+
publishPages();
|
|
62
|
+
}
|
|
63
|
+
function setStatus({ status }, _optional = {}) {
|
|
64
|
+
if (store.signal.aborted || status === store.getSnapshot().status)
|
|
65
|
+
return;
|
|
66
|
+
resetMorePages();
|
|
67
|
+
firstPage = null;
|
|
68
|
+
firstError = null;
|
|
69
|
+
store.set({ patch: { status, items: null, nextCursor: null, error: null, rowState: {} } });
|
|
70
|
+
}
|
|
71
|
+
function settleFirstPage({ page, error, status }, _optional = {}) {
|
|
72
|
+
if (store.signal.aborted || status !== store.getSnapshot().status)
|
|
73
|
+
return;
|
|
74
|
+
// A successful new page drops stale cursor pages. Error-only notifications do not erase
|
|
75
|
+
// already rendered data or invalidate a current cursor read.
|
|
76
|
+
if (page !== firstPage) {
|
|
77
|
+
resetMorePages();
|
|
78
|
+
firstPage = page;
|
|
79
|
+
store.set({ patch: { nextCursor: page?.nextCursor ?? null } });
|
|
80
|
+
}
|
|
81
|
+
firstError = error;
|
|
82
|
+
publishPages();
|
|
83
|
+
}
|
|
84
|
+
async function loadMore(_required = {}, _optional = {}) {
|
|
85
|
+
const { nextCursor, status } = store.getSnapshot();
|
|
86
|
+
if (store.signal.aborted || !nextCursor || loadingMore)
|
|
87
|
+
return;
|
|
88
|
+
loadingMore = true;
|
|
89
|
+
const generation = ++pageGeneration;
|
|
90
|
+
moreError = null; // A retry clears the prior failure before its request settles.
|
|
91
|
+
store.set({ patch: { loadingMore: true } });
|
|
92
|
+
publishPages();
|
|
93
|
+
try {
|
|
94
|
+
const page = await api.listCommentsQueue({}, { status, cursor: nextCursor });
|
|
95
|
+
if (generation !== pageGeneration || store.signal.aborted)
|
|
96
|
+
return;
|
|
97
|
+
morePages = [...morePages, ...page.items];
|
|
98
|
+
store.set({ patch: { nextCursor: page.nextCursor } });
|
|
99
|
+
publishPages();
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (generation !== pageGeneration || store.signal.aborted)
|
|
103
|
+
return;
|
|
104
|
+
moreError = describeApiError({ e, fallback: t('failed to load the moderation queue') });
|
|
105
|
+
publishPages();
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
// The reset already released a superseded call's lock; it must not unlock a newer call.
|
|
109
|
+
if (generation === pageGeneration && !store.signal.aborted) {
|
|
110
|
+
loadingMore = false;
|
|
111
|
+
store.set({ patch: { loadingMore: false } });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async function onModerate({ comment, action }, _optional = {}) {
|
|
116
|
+
const permission = action === 'trash' ? 'comments.delete' : 'comments.moderate';
|
|
117
|
+
if (store.signal.aborted || !hasPermission({ permissions, permission }) || busyRowIds.has(comment.id))
|
|
118
|
+
return;
|
|
119
|
+
busyRowIds.add(comment.id);
|
|
120
|
+
patchRowState(comment.id, { busy: true, error: null });
|
|
121
|
+
try {
|
|
122
|
+
await api.moderateComment({ commentId: comment.id, action, expectedVersion: comment.version });
|
|
123
|
+
if (!store.signal.aborted)
|
|
124
|
+
reloadAfterAction();
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
patchRowState(comment.id, { busy: false, error: describeModerationError({ e }, { t }) });
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
busyRowIds.delete(comment.id);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function setPendingPurge({ comment }, _optional = {}) {
|
|
134
|
+
store.set({ patch: { pendingPurge: comment } });
|
|
135
|
+
}
|
|
136
|
+
/** Confirmation closes on success and failure. Errors remain on the affected row. */
|
|
137
|
+
async function onPurge(_required = {}, _optional = {}) {
|
|
138
|
+
const comment = store.getSnapshot().pendingPurge;
|
|
139
|
+
if (store.signal.aborted || !comment || !hasPermission({ permissions, permission: 'comments.delete.force' }) || busyRowIds.has(comment.id))
|
|
140
|
+
return;
|
|
141
|
+
busyRowIds.add(comment.id);
|
|
142
|
+
patchRowState(comment.id, { busy: true, error: null });
|
|
143
|
+
try {
|
|
144
|
+
await api.purgeComment({ commentId: comment.id });
|
|
145
|
+
if (!store.signal.aborted)
|
|
146
|
+
reloadAfterAction();
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
patchRowState(comment.id, { busy: false, error: describeApiError({ e, fallback: t('Failed to purge comment.') }) });
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
busyRowIds.delete(comment.id);
|
|
153
|
+
setPendingPurge({ comment: null });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function dispose(_required = {}, _optional = {}) {
|
|
157
|
+
pageGeneration++;
|
|
158
|
+
busyRowIds.clear();
|
|
159
|
+
store.dispose();
|
|
160
|
+
}
|
|
161
|
+
return { getSnapshot: store.getSnapshot, subscribe: store.subscribe, dispose, stateFor,
|
|
162
|
+
configure, setStatus, settleFirstPage, loadMore, onModerate, setPendingPurge, onPurge };
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=comment-queue.controller.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AdminCommentsPort, CommentsSettings } from '../../core/ports/comments.js';
|
|
2
|
+
import type { CommentSettingsState } from '../models.js';
|
|
3
|
+
import { type CommentsTranslator } from '../messages.en.js';
|
|
4
|
+
/** Own the uncontrolled form's diff baseline, validation and server-confirmed save.
|
|
5
|
+
* The query cache owns reads; the FIRST successful read seeds the baseline once.
|
|
6
|
+
* @returns An instance store with seed/save operations; action grants default denied.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCommentSettingsController({ api, permissions }: {
|
|
9
|
+
api: AdminCommentsPort;
|
|
10
|
+
permissions?: readonly string[];
|
|
11
|
+
}, { t, onInvalidate }?: {
|
|
12
|
+
t?: CommentsTranslator;
|
|
13
|
+
onInvalidate?: () => void;
|
|
14
|
+
}): {
|
|
15
|
+
getSnapshot: () => Readonly<CommentSettingsState>;
|
|
16
|
+
subscribe: ({ listener }: {
|
|
17
|
+
listener: () => void;
|
|
18
|
+
}) => () => void;
|
|
19
|
+
dispose: () => void;
|
|
20
|
+
configure: ({ permissions: nextPermissions, t: nextTranslator }: {
|
|
21
|
+
permissions: readonly string[];
|
|
22
|
+
t: CommentsTranslator;
|
|
23
|
+
}, _optional?: Record<string, never>) => void;
|
|
24
|
+
settleRead: ({ settings, error }: {
|
|
25
|
+
settings: CommentsSettings | null;
|
|
26
|
+
error: Error | null;
|
|
27
|
+
}, _optional?: Record<string, never>) => void;
|
|
28
|
+
save: ({ form }: {
|
|
29
|
+
form: FormData;
|
|
30
|
+
}, _optional?: Record<string, never>) => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=comment-settings.controller.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { createControllerStore } from '../../core/module/controller-store.js';
|
|
2
|
+
import { hasPermission } from '../../core/permissions/rules.js';
|
|
3
|
+
import { buildSettingsPatch, validateSettingsPatch, visibleCommentSettingsError } from '../rules.js';
|
|
4
|
+
import { englishComments } from '../messages.en.js';
|
|
5
|
+
/** Own the uncontrolled form's diff baseline, validation and server-confirmed save.
|
|
6
|
+
* The query cache owns reads; the FIRST successful read seeds the baseline once.
|
|
7
|
+
* @returns An instance store with seed/save operations; action grants default denied.
|
|
8
|
+
*/
|
|
9
|
+
export function createCommentSettingsController({ api, permissions = [] }, { t = englishComments, onInvalidate } = {}) {
|
|
10
|
+
const store = createControllerStore({ initial: { settings: null, error: null, saving: false, notice: null } });
|
|
11
|
+
let canConfigure = hasPermission({ permissions, permission: 'comments.configure' });
|
|
12
|
+
let seeded = false;
|
|
13
|
+
let listError = null;
|
|
14
|
+
let saveError = null;
|
|
15
|
+
let validationError = null;
|
|
16
|
+
function publishError() {
|
|
17
|
+
store.set({ patch: { error: visibleCommentSettingsError({ validationError, saveError,
|
|
18
|
+
saveFallback: t('failed to save Comments settings'), listError,
|
|
19
|
+
listFallback: t('failed to load Comments settings'), hasSettings: store.getSnapshot().settings !== null }) } });
|
|
20
|
+
}
|
|
21
|
+
/** Update grants/copy while preserving the one-shot uncontrolled-form baseline. */
|
|
22
|
+
function configure({ permissions: nextPermissions, t: nextTranslator }, _optional = {}) {
|
|
23
|
+
if (store.signal.aborted)
|
|
24
|
+
return;
|
|
25
|
+
canConfigure = hasPermission({ permissions: nextPermissions, permission: 'comments.configure' });
|
|
26
|
+
t = nextTranslator;
|
|
27
|
+
publishError();
|
|
28
|
+
}
|
|
29
|
+
function settleRead({ settings, error }, _optional = {}) {
|
|
30
|
+
if (!canConfigure || store.signal.aborted)
|
|
31
|
+
return;
|
|
32
|
+
// TM-2026-08-12-A: changing defaultValue/defaultChecked does not change an already mounted
|
|
33
|
+
// uncontrolled input. Reseeding its diff baseline on a background refetch would quietly
|
|
34
|
+
// revert another operator's committed field on the next unrelated save. Only this operator's
|
|
35
|
+
// own save may advance it. Accepted trade: the view stays stale until reload; controlled
|
|
36
|
+
// drafts and server compare-and-swap were considered and deliberately deferred.
|
|
37
|
+
if (settings && !seeded) {
|
|
38
|
+
seeded = true;
|
|
39
|
+
store.set({ patch: { settings } });
|
|
40
|
+
}
|
|
41
|
+
listError = error;
|
|
42
|
+
publishError();
|
|
43
|
+
}
|
|
44
|
+
async function save({ form }, _optional = {}) {
|
|
45
|
+
const settings = store.getSnapshot().settings;
|
|
46
|
+
if (!canConfigure || !settings || store.signal.aborted)
|
|
47
|
+
return;
|
|
48
|
+
store.set({ patch: { notice: null } });
|
|
49
|
+
const patch = buildSettingsPatch({ form, current: settings });
|
|
50
|
+
// Validate before sending, matching the backend's spam score bound.
|
|
51
|
+
validationError = validateSettingsPatch({ patch }, { t });
|
|
52
|
+
if (validationError) {
|
|
53
|
+
publishError();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
saveError = null;
|
|
57
|
+
store.set({ patch: { saving: true } });
|
|
58
|
+
publishError();
|
|
59
|
+
try {
|
|
60
|
+
const updated = await api.putCommentsSettings({}, patch);
|
|
61
|
+
if (store.signal.aborted)
|
|
62
|
+
return;
|
|
63
|
+
onInvalidate?.();
|
|
64
|
+
// Read-your-writes must settle immediately; cache invalidation is deliberately not awaited.
|
|
65
|
+
store.set({ patch: { settings: updated, notice: t('Saved.') } });
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
saveError = e instanceof Error ? e : new Error(t('failed to save Comments settings'));
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
store.set({ patch: { saving: false } });
|
|
72
|
+
publishError();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { getSnapshot: store.getSnapshot, subscribe: store.subscribe, dispose: store.dispose, configure, settleRead, save };
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=comment-settings.controller.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CommentsState } from '../models.js';
|
|
2
|
+
/** Permissions settle from the shared query cache; absent grants default to denied. */
|
|
3
|
+
export declare function createCommentsController(_required: Record<string, never>, _optional?: Record<string, never>): {
|
|
4
|
+
getSnapshot: () => Readonly<CommentsState>;
|
|
5
|
+
subscribe: ({ listener }: {
|
|
6
|
+
listener: () => void;
|
|
7
|
+
}) => () => void;
|
|
8
|
+
dispose: () => void;
|
|
9
|
+
settle({ data, error }: {
|
|
10
|
+
data: {
|
|
11
|
+
effectivePermissions?: readonly string[];
|
|
12
|
+
} | null;
|
|
13
|
+
error: Error | null;
|
|
14
|
+
}, _options?: Record<string, never>): void;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=comments.controller.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createControllerStore } from '../../core/module/controller-store.js';
|
|
2
|
+
import { describeApiError } from '../../core/transport/errors.js';
|
|
3
|
+
/** Permissions settle from the shared query cache; absent grants default to denied. */
|
|
4
|
+
export function createCommentsController(_required, _optional = {}) {
|
|
5
|
+
const store = createControllerStore({ initial: { permissions: null, error: null } });
|
|
6
|
+
return {
|
|
7
|
+
getSnapshot: store.getSnapshot, subscribe: store.subscribe, dispose: store.dispose,
|
|
8
|
+
settle({ data, error }, _options = {}) {
|
|
9
|
+
store.set({ patch: {
|
|
10
|
+
permissions: data ? [...(data.effectivePermissions ?? [])] : null,
|
|
11
|
+
error: error ? describeApiError({ e: error, fallback: 'failed to load permissions' }) : null,
|
|
12
|
+
} });
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=comments.controller.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { commentsModule } from './comments.module.js';
|
|
2
|
+
export { commentsApiToken, commentsSessionToken, commentsEventsToken } from './ports.js';
|
|
3
|
+
export type { CommentsSessionPort, CommentsEventsPort } from './ports.js';
|
|
4
|
+
export type { AdminComment, AdminCommentsPort, AdminCommentsQueuePage, CommentsSettings, CommentModerationAction, CommentStatus } from '../core/ports/comments.js';
|
|
5
|
+
export type { CommentsState, CommentQueueState, CommentSettingsState } from './models.js';
|
|
6
|
+
export { commentsMessagesEn, englishComments } from './messages.en.js';
|
|
7
|
+
export type { CommentsTranslator } from './messages.en.js';
|
|
8
|
+
export { createCommentsController } from './controllers/comments.controller.js';
|
|
9
|
+
export { createCommentQueueController } from './controllers/comment-queue.controller.js';
|
|
10
|
+
export { createCommentSettingsController } from './controllers/comment-settings.controller.js';
|
|
11
|
+
export { KEYS, COMMENTS_QUEUE_RESOURCE, buildSettingsPatch, commentRowMenuItems, describeModerationError, emptyRowState, parseCloseAfterDays, parseOptionalNumber, truncate, validateSettingsPatch, visibleCommentSettingsError } from './rules.js';
|
|
12
|
+
export type { RowActionState, CommentRowMenuHandlers } from './rules.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { commentsModule } from './comments.module.js';
|
|
2
|
+
export { commentsApiToken, commentsSessionToken, commentsEventsToken } from './ports.js';
|
|
3
|
+
export { commentsMessagesEn, englishComments } from './messages.en.js';
|
|
4
|
+
export { createCommentsController } from './controllers/comments.controller.js';
|
|
5
|
+
export { createCommentQueueController } from './controllers/comment-queue.controller.js';
|
|
6
|
+
export { createCommentSettingsController } from './controllers/comment-settings.controller.js';
|
|
7
|
+
export { KEYS, COMMENTS_QUEUE_RESOURCE, buildSettingsPatch, commentRowMenuItems, describeModerationError, emptyRowState, parseCloseAfterDays, parseOptionalNumber, truncate, validateSettingsPatch, visibleCommentSettingsError } from './rules.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** English source keys stay byte-identical to the host dictionaries. */
|
|
2
|
+
export declare const commentsMessagesEn: {
|
|
3
|
+
readonly Status: "Status";
|
|
4
|
+
readonly "Actions for the comment by \"{author}\"": "Actions for the comment by \"{author}\"";
|
|
5
|
+
readonly Author: "Author";
|
|
6
|
+
readonly Comment: "Comment";
|
|
7
|
+
readonly Depth: "Depth";
|
|
8
|
+
readonly Created: "Created";
|
|
9
|
+
readonly More: "More";
|
|
10
|
+
readonly "Loading\u2026": "Loading…";
|
|
11
|
+
readonly "Load more": "Load more";
|
|
12
|
+
readonly "Loading comments\u2026": "Loading comments…";
|
|
13
|
+
readonly "No {status} comments.": "No {status} comments.";
|
|
14
|
+
readonly "Permanently delete this comment?": "Permanently delete this comment?";
|
|
15
|
+
readonly "Permanently delete this comment by \"{author}\"? This cannot be undone.": "Permanently delete this comment by \"{author}\"? This cannot be undone.";
|
|
16
|
+
readonly "Permanently delete": "Permanently delete";
|
|
17
|
+
readonly "Loading Comments settings\u2026": "Loading Comments settings…";
|
|
18
|
+
readonly Settings: "Settings";
|
|
19
|
+
readonly "Comments enabled": "Comments enabled";
|
|
20
|
+
readonly "Require moderation (new comments start pending)": "Require moderation (new comments start pending)";
|
|
21
|
+
readonly "Max thread depth": "Max thread depth";
|
|
22
|
+
readonly "Close submissions after (days, blank = never)": "Close submissions after (days, blank = never)";
|
|
23
|
+
readonly "Spam auto-reject score (0\u20131)": "Spam auto-reject score (0–1)";
|
|
24
|
+
readonly "Max submissions per IP per hour": "Max submissions per IP per hour";
|
|
25
|
+
readonly "Saving\u2026": "Saving…";
|
|
26
|
+
readonly "Save settings": "Save settings";
|
|
27
|
+
readonly "Loading Comments\u2026": "Loading Comments…";
|
|
28
|
+
readonly People: "People";
|
|
29
|
+
readonly Comments: "Comments";
|
|
30
|
+
readonly "Moderate incoming comments and configure workspace-wide comment behavior.": "Moderate incoming comments and configure workspace-wide comment behavior.";
|
|
31
|
+
readonly "You do not have permission to view the moderation queue.": "You do not have permission to view the moderation queue.";
|
|
32
|
+
readonly "This comment changed since you loaded it (current version {currentVersion}) \u2014 refresh and try again.": "This comment changed since you loaded it (current version {currentVersion}) — refresh and try again.";
|
|
33
|
+
readonly "This comment changed since you loaded it \u2014 refresh and try again.": "This comment changed since you loaded it — refresh and try again.";
|
|
34
|
+
readonly "Failed to update comment.": "Failed to update comment.";
|
|
35
|
+
readonly Approve: "Approve";
|
|
36
|
+
readonly Spam: "Spam";
|
|
37
|
+
readonly Trash: "Trash";
|
|
38
|
+
readonly Restore: "Restore";
|
|
39
|
+
readonly Purge: "Purge";
|
|
40
|
+
readonly "Spam auto-reject score must be between 0 and 1.": "Spam auto-reject score must be between 0 and 1.";
|
|
41
|
+
readonly "failed to load the moderation queue": "failed to load the moderation queue";
|
|
42
|
+
readonly "Failed to purge comment.": "Failed to purge comment.";
|
|
43
|
+
readonly "Saved.": "Saved.";
|
|
44
|
+
readonly "failed to save Comments settings": "failed to save Comments settings";
|
|
45
|
+
readonly "failed to load Comments settings": "failed to load Comments settings";
|
|
46
|
+
readonly pending: "Pending";
|
|
47
|
+
readonly approved: "Approved";
|
|
48
|
+
readonly spam: "Spam";
|
|
49
|
+
readonly trash: "Trash";
|
|
50
|
+
};
|
|
51
|
+
export type CommentsTranslator = (key: string, vars?: Record<string, string | number>) => string;
|
|
52
|
+
/** Default copy; unknown keys remain visible and variables use the native string formatter. */
|
|
53
|
+
export declare const englishComments: CommentsTranslator;
|
|
54
|
+
//# sourceMappingURL=messages.en.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** English source keys stay byte-identical to the host dictionaries. */
|
|
2
|
+
export const commentsMessagesEn = {
|
|
3
|
+
"Status": "Status",
|
|
4
|
+
"Actions for the comment by \"{author}\"": "Actions for the comment by \"{author}\"",
|
|
5
|
+
"Author": "Author",
|
|
6
|
+
"Comment": "Comment",
|
|
7
|
+
"Depth": "Depth",
|
|
8
|
+
"Created": "Created",
|
|
9
|
+
"More": "More",
|
|
10
|
+
"Loading…": "Loading…",
|
|
11
|
+
"Load more": "Load more",
|
|
12
|
+
"Loading comments…": "Loading comments…",
|
|
13
|
+
"No {status} comments.": "No {status} comments.",
|
|
14
|
+
"Permanently delete this comment?": "Permanently delete this comment?",
|
|
15
|
+
"Permanently delete this comment by \"{author}\"? This cannot be undone.": "Permanently delete this comment by \"{author}\"? This cannot be undone.",
|
|
16
|
+
"Permanently delete": "Permanently delete",
|
|
17
|
+
"Loading Comments settings…": "Loading Comments settings…",
|
|
18
|
+
"Settings": "Settings",
|
|
19
|
+
"Comments enabled": "Comments enabled",
|
|
20
|
+
"Require moderation (new comments start pending)": "Require moderation (new comments start pending)",
|
|
21
|
+
"Max thread depth": "Max thread depth",
|
|
22
|
+
"Close submissions after (days, blank = never)": "Close submissions after (days, blank = never)",
|
|
23
|
+
"Spam auto-reject score (0–1)": "Spam auto-reject score (0–1)",
|
|
24
|
+
"Max submissions per IP per hour": "Max submissions per IP per hour",
|
|
25
|
+
"Saving…": "Saving…",
|
|
26
|
+
"Save settings": "Save settings",
|
|
27
|
+
"Loading Comments…": "Loading Comments…",
|
|
28
|
+
"People": "People",
|
|
29
|
+
"Comments": "Comments",
|
|
30
|
+
"Moderate incoming comments and configure workspace-wide comment behavior.": "Moderate incoming comments and configure workspace-wide comment behavior.",
|
|
31
|
+
"You do not have permission to view the moderation queue.": "You do not have permission to view the moderation queue.",
|
|
32
|
+
"This comment changed since you loaded it (current version {currentVersion}) — refresh and try again.": "This comment changed since you loaded it (current version {currentVersion}) — refresh and try again.",
|
|
33
|
+
"This comment changed since you loaded it — refresh and try again.": "This comment changed since you loaded it — refresh and try again.",
|
|
34
|
+
"Failed to update comment.": "Failed to update comment.",
|
|
35
|
+
"Approve": "Approve",
|
|
36
|
+
"Spam": "Spam",
|
|
37
|
+
"Trash": "Trash",
|
|
38
|
+
"Restore": "Restore",
|
|
39
|
+
"Purge": "Purge",
|
|
40
|
+
"Spam auto-reject score must be between 0 and 1.": "Spam auto-reject score must be between 0 and 1.",
|
|
41
|
+
"failed to load the moderation queue": "failed to load the moderation queue",
|
|
42
|
+
"Failed to purge comment.": "Failed to purge comment.",
|
|
43
|
+
"Saved.": "Saved.",
|
|
44
|
+
"failed to save Comments settings": "failed to save Comments settings",
|
|
45
|
+
"failed to load Comments settings": "failed to load Comments settings",
|
|
46
|
+
"pending": "Pending",
|
|
47
|
+
"approved": "Approved",
|
|
48
|
+
"spam": "Spam",
|
|
49
|
+
"trash": "Trash"
|
|
50
|
+
};
|
|
51
|
+
/** Default copy; unknown keys remain visible and variables use the native string formatter. */
|
|
52
|
+
export const englishComments = (key, vars = {}) => {
|
|
53
|
+
const template = Object.hasOwn(commentsMessagesEn, key) ? commentsMessagesEn[key] : key;
|
|
54
|
+
return template.replace(/\{(\w+)\}/g, (placeholder, name) => vars[name] === undefined ? placeholder : String(vars[name]));
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=messages.en.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AdminComment, CommentsSettings, CommentStatus } from '../core/ports/comments.js';
|
|
2
|
+
import type { RowActionState } from './rules.js';
|
|
3
|
+
export interface CommentsState {
|
|
4
|
+
readonly permissions: readonly string[] | null;
|
|
5
|
+
readonly error: string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface CommentQueueState {
|
|
8
|
+
readonly status: CommentStatus;
|
|
9
|
+
readonly items: readonly AdminComment[] | null;
|
|
10
|
+
readonly nextCursor: string | null;
|
|
11
|
+
readonly error: string | null;
|
|
12
|
+
readonly loadingMore: boolean;
|
|
13
|
+
readonly rowState: Readonly<Record<string, RowActionState>>;
|
|
14
|
+
readonly pendingPurge: AdminComment | null;
|
|
15
|
+
}
|
|
16
|
+
export interface CommentSettingsState {
|
|
17
|
+
readonly settings: CommentsSettings | null;
|
|
18
|
+
readonly error: string | null;
|
|
19
|
+
readonly saving: boolean;
|
|
20
|
+
readonly notice: string | null;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AdminCommentsPort } from '../core/ports/comments.js';
|
|
2
|
+
import type { AdminAuthPort } from '../core/ports/auth.js';
|
|
3
|
+
/** Session reads reuse the auth owner; no comments-specific permission endpoint exists. */
|
|
4
|
+
export type CommentsSessionPort = Pick<AdminAuthPort, 'me'>;
|
|
5
|
+
/** The host filters notifications to the moderation queue. Settings intentionally never subscribe. */
|
|
6
|
+
export interface CommentsEventsPort {
|
|
7
|
+
subscribe(required: {
|
|
8
|
+
onRefresh: () => void;
|
|
9
|
+
}, optional?: Record<string, never>): () => void;
|
|
10
|
+
}
|
|
11
|
+
export declare const commentsApiToken: import("../core/module/token.js").AdminPortToken<AdminCommentsPort, "admin.comments.api">;
|
|
12
|
+
export declare const commentsSessionToken: import("../core/module/token.js").AdminPortToken<CommentsSessionPort, "admin.comments.session">;
|
|
13
|
+
export declare const commentsEventsToken: import("../core/module/token.js").AdminPortToken<CommentsEventsPort, "admin.comments.events">;
|
|
14
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { adminPort } from '../core/module/token.js';
|
|
2
|
+
export const commentsApiToken = adminPort({ id: 'admin.comments.api' });
|
|
3
|
+
export const commentsSessionToken = adminPort({ id: 'admin.comments.session' });
|
|
4
|
+
export const commentsEventsToken = adminPort({ id: 'admin.comments.events' });
|
|
5
|
+
//# sourceMappingURL=ports.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AdminComment, CommentModerationAction, CommentStatus } from '../../../core/ports/comments.js';
|
|
2
|
+
import type { CommentsTranslator } from '../../messages.en.js';
|
|
3
|
+
import type { RowActionState } from '../../rules.js';
|
|
4
|
+
import { useWiredCommentQueue } from '../hooks/use-comment-queue.hooks.js';
|
|
5
|
+
/** The moderation-queue table's "More" column — a `RowMenu` built from `commentRowMenuItems`, or
|
|
6
|
+
* an em dash when the operator's permissions leave no items, plus this row's own error (if the
|
|
7
|
+
* last action against it failed). Top-level rather than an inline `cell` closure so it has its
|
|
8
|
+
* own directly-testable scope, per `commentRowMenuItems`'s own risk ranking. */
|
|
9
|
+
export declare function QueueActionsCell(props: {
|
|
10
|
+
comment: AdminComment;
|
|
11
|
+
agentHandleBase: string;
|
|
12
|
+
permissions: readonly string[];
|
|
13
|
+
status: CommentStatus;
|
|
14
|
+
rowState: RowActionState;
|
|
15
|
+
t: CommentsTranslator;
|
|
16
|
+
onModerate: (comment: AdminComment, action: CommentModerationAction) => void;
|
|
17
|
+
onRequestPurge: (comment: AdminComment) => void;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
19
|
+
export interface QueueSectionProps {
|
|
20
|
+
permissions: readonly string[];
|
|
21
|
+
t?: CommentsTranslator;
|
|
22
|
+
/** Dependency injection seam for tests — the same convention `@jini-ai/ui`'s `CustomSelect` uses
|
|
23
|
+
* for `useCustomSelect`. Defaulted to the real hook, so production callers (the exported
|
|
24
|
+
* `Comments` below) pass nothing and behave exactly as before. */
|
|
25
|
+
useCommentQueueHook?: typeof useWiredCommentQueue;
|
|
26
|
+
}
|
|
27
|
+
/** Exported (2026-08-14, previously module-private) so `QueueSection.unit.test.tsx` can drive its
|
|
28
|
+
* own DI seam directly — the same reason `AiAssistant.tsx`'s `AdminExecutionMode` is exported. */
|
|
29
|
+
export declare function QueueSection(props: QueueSectionProps): import("react").JSX.Element;
|
|
30
|
+
//# sourceMappingURL=QueueSection.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { DataTable } from '../../../react/components/DataTable.js';
|
|
3
|
+
import { RowMenu } from '../../../react/components/RowMenu/RowMenu.js';
|
|
4
|
+
import { ConfirmDialog } from '../../../react/components/ConfirmDialog/ConfirmDialog.js';
|
|
5
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
6
|
+
import { interpolate } from '@jini-ai/ui/panel-kit';
|
|
7
|
+
import { useWiredCommentQueue } from '../hooks/use-comment-queue.hooks.js';
|
|
8
|
+
import { useQueueSection, useQueueActionsCell, useQueueTable, useQueueToolbar } from '../hooks/QueueSection.hooks.js';
|
|
9
|
+
const STATUS_OPTIONS = ["pending", "approved", "spam", "trash"];
|
|
10
|
+
/** The status-filter `<select>` — pure presentation, no state of its own. */
|
|
11
|
+
function QueueToolbar({ status, onStatusChange, t, }) {
|
|
12
|
+
const { onChange } = useQueueToolbar({ onStatusChange });
|
|
13
|
+
return (_jsx("div", { className: "toolbar", children: _jsxs("div", { className: "field", children: [_jsx("label", { className: "field-label", htmlFor: "comments-status-filter", children: t("Status") }), _jsx("select", { id: "comments-status-filter", value: status, onChange: onChange, ...agentHandle({ handle: "comments-status-filter" }, { role: "field", label: "Filter the moderation queue by status" }), children: STATUS_OPTIONS.map((s) => (_jsx("option", { value: s, children: t(s) }, s))) })] }) }));
|
|
14
|
+
}
|
|
15
|
+
/** The moderation-queue table's "More" column — a `RowMenu` built from `commentRowMenuItems`, or
|
|
16
|
+
* an em dash when the operator's permissions leave no items, plus this row's own error (if the
|
|
17
|
+
* last action against it failed). Top-level rather than an inline `cell` closure so it has its
|
|
18
|
+
* own directly-testable scope, per `commentRowMenuItems`'s own risk ranking. */
|
|
19
|
+
export function QueueActionsCell(props) {
|
|
20
|
+
const { menuItems } = useQueueActionsCell(props);
|
|
21
|
+
return (_jsxs(_Fragment, { children: [menuItems.length > 0 ? (_jsx(RowMenu, { triggerLabel: interpolate({ template: props.t('Actions for the comment by "{author}"'), vars: {
|
|
22
|
+
author: props.comment.authorName,
|
|
23
|
+
} }), agentHandle: `${props.agentHandleBase}-menu`, items: menuItems })) : (_jsx("span", { className: "muted-cell", children: "\u2014" })), props.rowState.error ? (_jsx("div", { className: "notice error", role: "alert", children: props.rowState.error })) : null] }));
|
|
24
|
+
}
|
|
25
|
+
/** The populated-queue view: the table plus its "Load more" pager. Only rendered once
|
|
26
|
+
* `QueueItemsView` has already ruled out the loading/empty states. */
|
|
27
|
+
function QueueTable(props) {
|
|
28
|
+
const { columns } = useQueueTable(props);
|
|
29
|
+
return (_jsxs(_Fragment, { children: [_jsx(DataTable, { rows: props.items, rowKey: (comment) => comment.id, columns: columns }), props.nextCursor ? (_jsx("button", { type: "button", className: "btn-secondary", onClick: props.loadMore, disabled: props.loadingMore, ...agentHandle({ handle: "comments-load-more" }, { role: "button", label: "Load more comments" }), children: props.loadingMore ? props.t("Loading…") : props.t("Load more") })) : null] }));
|
|
30
|
+
}
|
|
31
|
+
/** Dispatches between the three queue-body states (loading / empty / populated) as a flat
|
|
32
|
+
* if-chain instead of a nested ternary — the nesting was the cognitive-complexity cost in the
|
|
33
|
+
* original inline JSX, not the branch count itself. */
|
|
34
|
+
function QueueItemsView(props) {
|
|
35
|
+
if (!props.items)
|
|
36
|
+
return _jsx("div", { className: "notice", children: props.t("Loading comments…") });
|
|
37
|
+
if (props.items.length === 0) {
|
|
38
|
+
return (_jsx("div", { className: "card", children: _jsx("div", { className: "empty-state", children: _jsx("p", { children: interpolate({ template: props.t("No {status} comments."), vars: { status: props.status } }) }) }) }));
|
|
39
|
+
}
|
|
40
|
+
return _jsx(QueueTable, { ...props, items: props.items });
|
|
41
|
+
}
|
|
42
|
+
/** The Purge confirm dialog. Stays mounted unconditionally (driven by `open`) — see
|
|
43
|
+
* `useCommentQueue`'s `pendingPurge` doc comment for why. */
|
|
44
|
+
function QueuePurgeDialog(props) {
|
|
45
|
+
return (_jsx(ConfirmDialog, { open: props.pendingPurge !== null, agentHandle: "comments-purge", title: props.t("Permanently delete this comment?"), body: props.pendingPurge ? (_jsx("p", { children: interpolate({ template: props.t('Permanently delete this comment by "{author}"? This cannot be undone.'), vars: {
|
|
46
|
+
author: props.pendingPurge.authorName,
|
|
47
|
+
} }) })) : null, confirmLabel: props.t("Permanently delete"), destructive: true, pending: props.busy, onConfirm: props.onConfirm, onCancel: props.onCancel }));
|
|
48
|
+
}
|
|
49
|
+
/** Exported (2026-08-14, previously module-private) so `QueueSection.unit.test.tsx` can drive its
|
|
50
|
+
* own DI seam directly — the same reason `AiAssistant.tsx`'s `AdminExecutionMode` is exported. */
|
|
51
|
+
export function QueueSection(props) {
|
|
52
|
+
const { t, status, setStatus, items, nextCursor, error, loadingMore, loadMore, stateFor, onModerate, pendingPurge, setPendingPurge, onPurge, onCancelPurge, purgeBusy, } = useQueueSection(props);
|
|
53
|
+
if (error && !items)
|
|
54
|
+
return _jsx("div", { className: "notice error", children: error });
|
|
55
|
+
return (_jsxs("div", { children: [_jsx(QueueToolbar, { status: status, onStatusChange: setStatus, t: t }), error ? _jsx("div", { className: "notice error", children: error }) : null, _jsx(QueueItemsView, { items: items, status: status, nextCursor: nextCursor, loadingMore: loadingMore, loadMore: loadMore, permissions: props.permissions, stateFor: stateFor, t: t, onModerate: onModerate, onRequestPurge: setPendingPurge }), _jsx(QueuePurgeDialog, { pendingPurge: pendingPurge, busy: purgeBusy, t: t, onConfirm: onPurge, onCancel: onCancelPurge })] }));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=QueueSection.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CommentsTranslator } from '../../messages.en.js';
|
|
2
|
+
import { useWiredCommentSettings } from '../hooks/use-comment-settings.hooks.js';
|
|
3
|
+
export interface SettingsSectionProps {
|
|
4
|
+
canConfigure: boolean;
|
|
5
|
+
t?: CommentsTranslator;
|
|
6
|
+
/** Dependency injection seam for tests — the same convention `@jini-ai/ui`'s `CustomSelect` uses
|
|
7
|
+
* for `useCustomSelect`. Defaulted to the real hook, so production callers (the exported
|
|
8
|
+
* `Comments` below) pass nothing and behave exactly as before. */
|
|
9
|
+
useCommentSettingsHook?: typeof useWiredCommentSettings;
|
|
10
|
+
}
|
|
11
|
+
/** Exported (2026-08-14, previously module-private) so `SettingsSection.unit.test.tsx` can drive
|
|
12
|
+
* its own DI seam directly — see `QueueSection`'s identical doc comment above. */
|
|
13
|
+
export declare function SettingsSection(props: SettingsSectionProps): import("react").JSX.Element | null;
|
|
14
|
+
//# sourceMappingURL=SettingsSection.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
3
|
+
import { useWiredCommentSettings } from '../hooks/use-comment-settings.hooks.js';
|
|
4
|
+
import { useSettingsSection } from '../hooks/SettingsSection.hooks.js';
|
|
5
|
+
/** Exported (2026-08-14, previously module-private) so `SettingsSection.unit.test.tsx` can drive
|
|
6
|
+
* its own DI seam directly — see `QueueSection`'s identical doc comment above. */
|
|
7
|
+
export function SettingsSection(props) {
|
|
8
|
+
const { settings, error, saving, notice, onSubmit, t } = useSettingsSection(props);
|
|
9
|
+
if (!props.canConfigure)
|
|
10
|
+
return null;
|
|
11
|
+
if (error && !settings)
|
|
12
|
+
return _jsx("div", { className: "notice error", children: error });
|
|
13
|
+
if (!settings)
|
|
14
|
+
return _jsx("div", { className: "notice", children: t("Loading Comments settings…") });
|
|
15
|
+
return (_jsxs("div", { children: [_jsx("h2", { children: t("Settings") }), error ? _jsx("div", { className: "notice error", children: error }) : null, notice ? _jsx("div", { className: "notice", children: notice }) : null, _jsxs("form", { className: "card", onSubmit: onSubmit, children: [_jsxs("div", { className: "field-group", children: [_jsxs("label", { className: "form-checkbox-field", children: [_jsx("input", { type: "checkbox", name: "enabled", defaultChecked: settings.enabled, ...agentHandle({ handle: "comments-settings-enabled" }, { role: "field", label: "Whether comments are enabled at all" }) }), t("Comments enabled")] }), _jsxs("label", { className: "form-checkbox-field", children: [_jsx("input", { type: "checkbox", name: "requireModeration", defaultChecked: settings.requireModeration, ...agentHandle({ handle: "comments-settings-require-moderation" }, {
|
|
16
|
+
role: "field",
|
|
17
|
+
label: "Whether new comments start pending moderation",
|
|
18
|
+
}) }), t("Require moderation (new comments start pending)")] })] }), _jsx("div", { className: "field-group", children: _jsxs("div", { className: "field-row", children: [_jsxs("div", { className: "field", children: [_jsx("label", { className: "field-label", htmlFor: "comments-max-depth", children: t("Max thread depth") }), _jsx("input", { id: "comments-max-depth", type: "number", name: "maxDepth", min: 0, step: 1, defaultValue: settings.maxDepth, ...agentHandle({ handle: "comments-settings-max-depth" }, { role: "field", label: "Maximum comment thread depth" }) })] }), _jsxs("div", { className: "field", children: [_jsx("label", { className: "field-label", htmlFor: "comments-close-after-days", children: t("Close submissions after (days, blank = never)") }), _jsx("input", { id: "comments-close-after-days", type: "number", name: "closeAfterDays", min: 0, step: 1, defaultValue: settings.closeAfterDays ?? "", ...agentHandle({ handle: "comments-settings-close-after-days" }, {
|
|
19
|
+
role: "field",
|
|
20
|
+
label: "Days after which submissions close, blank for never",
|
|
21
|
+
}) })] }), _jsxs("div", { className: "field", children: [_jsx("label", { className: "field-label", htmlFor: "comments-spam-score", children: t("Spam auto-reject score (0–1)") }), _jsx("input", { id: "comments-spam-score", type: "number", name: "spamAutoRejectScore", min: 0, max: 1, step: 0.01, defaultValue: settings.spamAutoRejectScore, ...agentHandle({ handle: "comments-settings-spam-score" }, { role: "field", label: "Spam auto-reject score, 0 to 1" }) })] }), _jsxs("div", { className: "field", children: [_jsx("label", { className: "field-label", htmlFor: "comments-max-per-ip", children: t("Max submissions per IP per hour") }), _jsx("input", { id: "comments-max-per-ip", type: "number", name: "maxPerIpPerHour", min: 1, step: 1, defaultValue: settings.maxPerIpPerHour, ...agentHandle({ handle: "comments-settings-max-per-ip" }, { role: "field", label: "Maximum submissions per IP per hour" }) })] })] }) }), _jsx("div", { className: "editor-actions form-actions", children: _jsx("button", { type: "submit", disabled: saving, ...agentHandle({ handle: "comments-settings-save" }, { role: "button", label: "Save the comments settings" }), children: saving ? t("Saving…") : t("Save settings") }) })] })] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=SettingsSection.js.map
|