@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,28 @@
|
|
|
1
|
+
import type { AdminFormDefinition, AdminFormField } from '../../models.js';
|
|
2
|
+
export interface FormEditorFieldsBodyProps {
|
|
3
|
+
name: string;
|
|
4
|
+
onNameChange: (value: string) => void;
|
|
5
|
+
slug: string;
|
|
6
|
+
onSlugChange: (value: string) => void;
|
|
7
|
+
isNew: boolean;
|
|
8
|
+
fields: AdminFormField[];
|
|
9
|
+
existingFieldIds: string[];
|
|
10
|
+
onFieldsChange: (fields: AdminFormField[]) => void;
|
|
11
|
+
form: AdminFormDefinition | null;
|
|
12
|
+
saving: boolean;
|
|
13
|
+
onStatusToggle: () => void;
|
|
14
|
+
onSave: () => void;
|
|
15
|
+
/** Translator closure — see `FormEditor()`'s own `t`. */
|
|
16
|
+
t: (key: string) => string;
|
|
17
|
+
mode: "builder" | "html";
|
|
18
|
+
onModeChange: (mode: "builder" | "html") => void;
|
|
19
|
+
html: string;
|
|
20
|
+
onHtmlChange: (html: string) => void;
|
|
21
|
+
onCopyEmbed: () => void;
|
|
22
|
+
copyFeedback: string | null;
|
|
23
|
+
}
|
|
24
|
+
export declare function FormEditorFieldsBody(props: FormEditorFieldsBodyProps, _optional?: {}): import("react").JSX.Element;
|
|
25
|
+
/** The page-header title/description text — split out because `FormEditor`'s isNew-dependent copy
|
|
26
|
+
* (two ternaries, one with a `||` fallback) is otherwise indistinguishable, in the complexity
|
|
27
|
+
* count, from the branches that actually decide what's on screen. */
|
|
28
|
+
//# sourceMappingURL=FormEditorFieldsBody.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useFormFieldsBodyView } from "../hooks/forms-view.hooks.js";
|
|
3
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
4
|
+
import { FormFieldsEditor } from "./FormFieldsEditor.js";
|
|
5
|
+
export function FormEditorFieldsBody(props, _optional = {}) {
|
|
6
|
+
const handlers = useFormFieldsBodyView(props);
|
|
7
|
+
const { name, onNameChange, slug, onSlugChange, isNew, fields, existingFieldIds, onFieldsChange, form, saving, onStatusToggle, onSave, t, mode, onModeChange, html, onHtmlChange, onCopyEmbed, copyFeedback, } = props;
|
|
8
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "field-group", children: _jsxs("div", { className: "field-row", children: [_jsxs("div", { className: "field", children: [_jsx("label", { className: "field-label", htmlFor: "form-name", children: t("Name") }), _jsx("input", { id: "form-name", value: name, onChange: handlers.onName, ...agentHandle({ handle: "form-editor-name" }, { role: "field", label: "This form's display name" }) })] }), _jsxs("div", { className: "field", children: [_jsx("label", { className: "field-label", htmlFor: "form-slug", children: t("Slug") }), _jsx("input", { id: "form-slug", value: slug, disabled: !isNew, onChange: handlers.onSlug, ...agentHandle({ handle: "form-editor-slug" }, {
|
|
9
|
+
role: "field",
|
|
10
|
+
label: "This form's URL slug — only editable while creating a new form",
|
|
11
|
+
}) })] })] }) }), _jsxs("div", { className: "field-group", children: [_jsxs("div", { className: "segmented", role: "group", "aria-label": t("Form authoring mode"), children: [_jsx("button", { type: "button", className: mode === "builder" ? "is-active" : "", "aria-pressed": mode === "builder", onClick: handlers.onBuilder, children: t("Builder") }), _jsx("button", { type: "button", className: mode === "html" ? "is-active" : "", "aria-pressed": mode === "html", onClick: handlers.onHtmlMode, children: t("HTML") })] }), mode === "html" ? (_jsx("textarea", { className: "page-html-source", value: html, onChange: handlers.onHtml, spellCheck: false, "aria-label": t("Form HTML") })) : (_jsx("div", { className: "table-scroll", children: _jsx(FormFieldsEditor, { fields: fields, existingFieldIds: existingFieldIds, onChange: onFieldsChange, t: t }) }))] }), _jsxs("div", { className: "editor-actions form-actions", children: [form ? _jsx("button", { type: "button", className: "btn-secondary", onClick: onCopyEmbed, children: t("Copy HTML embed") }) : null, copyFeedback ? _jsx("span", { role: "status", children: copyFeedback }) : null, !isNew && form ? (
|
|
12
|
+
// Reversible-but-access-affecting (turns off the live site's ability to accept
|
|
13
|
+
// submissions through this form) — `.btn-warning`, not `.btn-danger`: nothing is
|
|
14
|
+
// deleted, and the same control flips right back to "Enable". Re-enabling is the safe
|
|
15
|
+
// direction, so it stays `.btn-secondary` rather than inheriting the warning look.
|
|
16
|
+
_jsx("button", { type: "button", className: form.status === "active" ? "btn-warning" : "btn-secondary", disabled: saving, onClick: onStatusToggle, ...agentHandle({ handle: "form-editor-status-toggle" }, {
|
|
17
|
+
role: "button",
|
|
18
|
+
label: "Disable or re-enable this form — disabling stops it accepting new submissions without deleting it",
|
|
19
|
+
}), children: form.status === "active" ? t("Disable") : t("Enable") })) : null, _jsx("button", { type: "button", disabled: saving, onClick: onSave, ...agentHandle({ handle: "form-editor-save" }, {
|
|
20
|
+
role: "button",
|
|
21
|
+
label: "Save this form's name, slug, fields and notification settings",
|
|
22
|
+
}), children: isNew ? t("Create form") : t("Save") })] })] }));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=FormEditorFieldsBody.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function FormEditorHeaderText(props: {
|
|
2
|
+
isNew: boolean;
|
|
3
|
+
name: string;
|
|
4
|
+
t: (key: string) => string;
|
|
5
|
+
}, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
6
|
+
/** The Fields/Submissions tab strip — renders only for an existing, loaded form (`showTabs`). */
|
|
7
|
+
//# sourceMappingURL=FormEditorHeaderText.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function FormEditorHeaderText(props, _optional = {}) {
|
|
3
|
+
const { isNew, name, t } = props;
|
|
4
|
+
return (_jsxs("div", { className: "page-header-text", children: [_jsx("p", { className: "page-kicker", children: t("Content") }), _jsx("h1", { className: "page-title", children: isNew ? t("New form") : name || t("Form") }), _jsx("p", { className: "page-description", children: isNew
|
|
5
|
+
? t("Configure a new form's fields.")
|
|
6
|
+
: t("Configure this form's fields, or review its submissions.") })] }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=FormEditorHeaderText.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { FormAnswerColumn } from '../../html-rules.js';
|
|
3
|
+
export declare function FormEditorMainPanel(props: {
|
|
4
|
+
isNew: boolean;
|
|
5
|
+
tab: "fields" | "submissions";
|
|
6
|
+
formId: string;
|
|
7
|
+
fieldsBody: React.ReactNode;
|
|
8
|
+
/** Translator closure — see `FormEditor()`'s own `t`. */
|
|
9
|
+
t: (key: string) => string;
|
|
10
|
+
answerColumns: FormAnswerColumn[];
|
|
11
|
+
}, _optional?: Record<string, never>): React.JSX.Element;
|
|
12
|
+
//# sourceMappingURL=FormEditorMainPanel.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FormSubmissions } from "./FormSubmissions.js";
|
|
3
|
+
export function FormEditorMainPanel(props, _optional = {}) {
|
|
4
|
+
const { isNew, tab, formId, fieldsBody, t, answerColumns } = props;
|
|
5
|
+
if (isNew) {
|
|
6
|
+
return _jsx("div", { className: "form-editor-panel", children: fieldsBody });
|
|
7
|
+
}
|
|
8
|
+
if (tab === "fields") {
|
|
9
|
+
return (_jsx("div", { className: "form-editor-panel", role: "tabpanel", id: "form-panel-fields", "aria-labelledby": "form-tab-fields", children: fieldsBody }));
|
|
10
|
+
}
|
|
11
|
+
return (_jsx("div", { className: "form-editor-panel", role: "tabpanel", id: "form-panel-submissions", "aria-labelledby": "form-tab-submissions", children: _jsx(FormSubmissions, { formId: formId, t: t, answerColumns: answerColumns }) }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=FormEditorMainPanel.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export declare function FormEditorTabStrip(props: {
|
|
3
|
+
showTabs: boolean;
|
|
4
|
+
tab: "fields" | "submissions";
|
|
5
|
+
onTabChange: (tab: "fields" | "submissions") => void;
|
|
6
|
+
tabRefs: React.MutableRefObject<Array<HTMLButtonElement | null>>;
|
|
7
|
+
onTabsKeyDown: (e: React.KeyboardEvent) => void;
|
|
8
|
+
/** Translator closure — see `FormEditor()`'s own `t`. */
|
|
9
|
+
t: (key: string) => string;
|
|
10
|
+
}, _optional?: Record<string, never>): React.JSX.Element | null;
|
|
11
|
+
/** Which card is showing below the tab strip: the fields form (always for `isNew`, or when the
|
|
12
|
+
* Fields tab is active) or the submissions table. */
|
|
13
|
+
//# sourceMappingURL=FormEditorTabStrip.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useFormTabStripView } from "../hooks/forms-view.hooks.js";
|
|
3
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
4
|
+
export function FormEditorTabStrip(props, _optional = {}) {
|
|
5
|
+
const { showTabs, tab, onTabChange, tabRefs, onTabsKeyDown, t } = props;
|
|
6
|
+
const tabs = useFormTabStripView({ onTabChange, tabRefs });
|
|
7
|
+
if (!showTabs)
|
|
8
|
+
return null;
|
|
9
|
+
return (_jsx("div", { className: "form-tabs", role: "tablist", "aria-label": t("Form sections"), onKeyDown: onTabsKeyDown, children: tabs.map((formTab) => (_jsx("button", { ref: formTab.ref, type: "button", role: "tab", id: `form-tab-${formTab.id}`, className: "form-tab", "aria-selected": tab === formTab.id, "aria-controls": `form-panel-${formTab.id}`, tabIndex: tab === formTab.id ? 0 : -1, onClick: formTab.onClick, ...agentHandle({ handle: `form-tab-${formTab.id}` }, {
|
|
10
|
+
role: "button",
|
|
11
|
+
label: formTab.id === "fields" ? "Switch to this form's Fields tab" : "Switch to this form's Submissions tab",
|
|
12
|
+
}), children: t(formTab.label) }, formTab.id))) }));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=FormEditorTabStrip.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AdminFormField } from '../../models.js';
|
|
2
|
+
import { useFormFieldsEditor } from '../hooks/use-form-fields-editor.hooks.js';
|
|
3
|
+
export interface FormFieldsEditorProps {
|
|
4
|
+
fields: AdminFormField[];
|
|
5
|
+
existingFieldIds?: string[];
|
|
6
|
+
onChange: (fields: AdminFormField[]) => void;
|
|
7
|
+
/** Dependency injection seam for tests — see `PostsProps.usePostsHook` for the convention. */
|
|
8
|
+
useFormFieldsEditorHook?: typeof useFormFieldsEditor;
|
|
9
|
+
/** Translator closure — see `FormEditor()`'s own `t`. */
|
|
10
|
+
t: (key: string) => string;
|
|
11
|
+
}
|
|
12
|
+
export declare function FormFieldsEditor({ fields, existingFieldIds, onChange, useFormFieldsEditorHook, t, }: FormFieldsEditorProps, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=FormFieldsEditor.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useFormFieldsView } from "../hooks/forms-view.hooks.js";
|
|
3
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
4
|
+
import { FIELD_TYPES } from '../../rules.js';
|
|
5
|
+
import { useFormFieldsEditor } from '../hooks/use-form-fields-editor.hooks.js';
|
|
6
|
+
import { FieldAttributesDialog } from "./FieldAttributesDialog.js";
|
|
7
|
+
export function FormFieldsEditor({ fields, existingFieldIds = [], onChange, useFormFieldsEditorHook = useFormFieldsEditor, t, }, _optional = {}) {
|
|
8
|
+
const controller = useFormFieldsEditorHook({ fields, onChange });
|
|
9
|
+
const { editingAttrsIndex, closeAttrsDialog, addField } = controller;
|
|
10
|
+
// Field ids are the form's own field vocabulary and are unique once saved, but a freshly-added
|
|
11
|
+
// row starts with an empty id (see `rules.ts`'s `blankField`) — `buildAgentListHandles`'s
|
|
12
|
+
// position fallback covers that case the same way it covers any other unsluggable id. Not
|
|
13
|
+
// `useMemo`d: one form's own field list is small and this is an O(n) pass, cheap enough that
|
|
14
|
+
// memoizing it was not judged worth the added indirection.
|
|
15
|
+
const { rows, editingField, saveAttributes } = useFormFieldsView({ fields, existingFieldIds, controller });
|
|
16
|
+
return (_jsxs(_Fragment, { children: [_jsxs("table", { className: "list-table form-fields-table", ...agentHandle({ handle: "form-fields-table" }, {
|
|
17
|
+
role: "region",
|
|
18
|
+
label: "This form's field definitions — one row per field, in the order they render on the live form",
|
|
19
|
+
}), children: [_jsxs("colgroup", { children: [_jsx("col", { style: { width: "14%" } }), _jsx("col", { style: { width: "17%" } }), _jsx("col", { style: { width: "17%" } }), _jsx("col", { style: { width: "8%" } }), _jsx("col", { style: { width: "18%" } }), _jsx("col", { style: { width: "8%" } }), _jsx("col", { style: { width: "18%" } })] }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t("ID") }), _jsx("th", { children: t("Label") }), _jsx("th", { children: t("Type") }), _jsx("th", { children: t("Req") }), _jsx("th", { children: t("Max length") }), _jsx("th", { children: t("More") }), _jsx("th", {})] }) }), _jsx("tbody", { children: rows.map(({ field, index, isExisting, base, displayName, onId, onLabel, onType, onRequired, onMaxLength, ref, onAttributes, onRemove }) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx("input", { "aria-label": `Field ${index + 1} id`, value: field.id, disabled: isExisting, onChange: onId, ...agentHandle({ handle: `${base}-id` }, {
|
|
20
|
+
role: "field",
|
|
21
|
+
label: "This field's unique id — the key its value is submitted under. Locked once saved.",
|
|
22
|
+
}) }) }), _jsx("td", { children: _jsx("input", { "aria-label": `Field ${index + 1} label`, value: field.label, onChange: onLabel, ...agentHandle({ handle: `${base}-label` }, { role: "field", label: "This field's on-page label" }) }) }), _jsx("td", { children: _jsx("select", { "aria-label": `Field ${index + 1} type`, value: field.type, onChange: onType, ...agentHandle({ handle: `${base}-type` }, {
|
|
23
|
+
role: "field",
|
|
24
|
+
label: "This field's input type — set with page.select_option, not click",
|
|
25
|
+
}), children: FIELD_TYPES.map((t) => (_jsx("option", { value: t, children: t }, t))) }) }), _jsx("td", { children: _jsx("input", { type: "checkbox", "aria-label": `Field ${index + 1} required`, checked: field.required, onChange: onRequired, ...agentHandle({ handle: `${base}-required` }, {
|
|
26
|
+
role: "checkbox",
|
|
27
|
+
label: "Whether this field must be filled in before the form can be submitted",
|
|
28
|
+
}) }) }), _jsx("td", { children: field.type === "checkbox" ? (_jsx("span", { "aria-hidden": "true", children: "\u2014" })) : (_jsx("input", { type: "number", "aria-label": `Field ${index + 1} max length`, value: field.maxLength ?? "", onChange: onMaxLength, ...agentHandle({ handle: `${base}-max-length` }, {
|
|
29
|
+
role: "field",
|
|
30
|
+
label: "The maximum number of characters this field accepts — blank means no limit",
|
|
31
|
+
}) })) }), _jsx("td", { children: _jsx("button", { ref: ref, type: "button", className: "row-menu-trigger", "aria-label": `Attributes for field "${displayName}"`, onClick: onAttributes, ...agentHandle({ handle: `${base}-attributes` }, {
|
|
32
|
+
role: "button",
|
|
33
|
+
label: "Open this field's CSS classes and HTML attributes dialog",
|
|
34
|
+
}), children: _jsxs("svg", { viewBox: "0 0 18 18", fill: "currentColor", "aria-hidden": "true", children: [_jsx("circle", { cx: "9", cy: "4.5", r: "1.5" }), _jsx("circle", { cx: "9", cy: "9", r: "1.5" }), _jsx("circle", { cx: "9", cy: "13.5", r: "1.5" })] }) }) }), _jsx("td", { children: _jsx("button", { type: "button", disabled: isExisting, title: isExisting ? t("Existing fields cannot be removed once created") : undefined, onClick: onRemove, ...agentHandle({ handle: `${base}-remove` }, {
|
|
35
|
+
role: "button",
|
|
36
|
+
label: "Remove this field from the form. Refused once the field has been saved.",
|
|
37
|
+
}), children: t("Remove") }) })] }, index))) }), _jsx("tfoot", { children: _jsx("tr", { children: _jsx("td", { colSpan: 7, children: _jsx("button", { type: "button", className: "btn-secondary", onClick: addField, ...agentHandle({ handle: "form-fields-add" }, { role: "button", label: "Add a new field to this form" }), children: t("Add field") }) }) }) })] }), editingAttrsIndex !== null && editingField ? (_jsx(FieldAttributesDialog, { field: editingField, fieldIndex: editingAttrsIndex, onSave: saveAttributes, onCancel: closeAttrsDialog, t: t })) : null] }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=FormFieldsEditor.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useWiredFormSubmissionDetail } from '../hooks/use-form-submission-detail.hooks.js';
|
|
2
|
+
import { type FormAnswerColumn } from '../../html-rules.js';
|
|
3
|
+
export interface FormSubmissionDetailProps {
|
|
4
|
+
formId: string;
|
|
5
|
+
submissionId: string;
|
|
6
|
+
onBack: () => void;
|
|
7
|
+
onDeleted: () => void;
|
|
8
|
+
/** Dependency injection seam for tests — see `PostsProps.usePostsHook` for the convention. */
|
|
9
|
+
useFormSubmissionDetailHook?: typeof useWiredFormSubmissionDetail;
|
|
10
|
+
/** Translator closure — see `FormEditor()`'s own `t`. */
|
|
11
|
+
t: (key: string) => string;
|
|
12
|
+
answerColumns?: readonly FormAnswerColumn[];
|
|
13
|
+
}
|
|
14
|
+
export declare function FormSubmissionDetail({ formId, submissionId, onBack, onDeleted, useFormSubmissionDetailHook, t, answerColumns, }: FormSubmissionDetailProps, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=FormSubmissionDetail.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ConfirmDialog } from '../../../react/components/ConfirmDialog/ConfirmDialog.js';
|
|
3
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
4
|
+
import { useWiredFormSubmissionDetail } from '../hooks/use-form-submission-detail.hooks.js';
|
|
5
|
+
import { useFormSubmissionDate } from '../hooks/use-form-submission-date.hooks.js';
|
|
6
|
+
import { FormSubmissionDate } from "./FormSubmissionDate.js";
|
|
7
|
+
import { formSubmissionRows } from '../../html-rules.js';
|
|
8
|
+
export function FormSubmissionDetail({ formId, submissionId, onBack, onDeleted, useFormSubmissionDetailHook = useWiredFormSubmissionDetail, t, answerColumns = [], }, _optional = {}) {
|
|
9
|
+
const formatDate = useFormSubmissionDate({});
|
|
10
|
+
const { submission, error, confirmOpen, deleting, requestDelete, cancelDelete, confirmDelete } = useFormSubmissionDetailHook({
|
|
11
|
+
formId,
|
|
12
|
+
submissionId,
|
|
13
|
+
onDeleted,
|
|
14
|
+
});
|
|
15
|
+
if (error && !submission)
|
|
16
|
+
return _jsx("div", { className: "notice error", children: error });
|
|
17
|
+
if (!submission)
|
|
18
|
+
return _jsx("div", { className: "notice", children: t("Loading submission…") });
|
|
19
|
+
return (
|
|
20
|
+
// `form-submission-detail` (`styles/forms.css`) — the back button, table, and Delete button
|
|
21
|
+
// were flush siblings with no gap between them (owner: "pad the buttons"), so the back
|
|
22
|
+
// button sat right on top of the table and Delete sat right underneath it. Same
|
|
23
|
+
// flex-column-plus-gap idiom `.field-group` already uses elsewhere for vertical rhythm,
|
|
24
|
+
// rather than one-off margins on each button.
|
|
25
|
+
_jsxs("div", { className: "form-submission-detail", children: [_jsxs("button", { type: "button", className: "btn-secondary", onClick: onBack, "aria-label": t("Back to submissions"), ...agentHandle({ handle: "form-submission-back" }, { role: "link", label: "Back to this form's list of submissions" }), children: ["\u2190 ", t("Back")] }), error ? _jsx("div", { className: "notice error", children: error }) : null, _jsx("div", { className: "table-scroll", children: _jsx("table", { className: "list-table", children: _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("th", { children: t("Submitted at") }), _jsx("td", { children: _jsx(FormSubmissionDate, { date: formatDate({ iso: submission.submittedAt }) }) })] }), _jsxs("tr", { children: [_jsx("th", { children: t("Source IP") }), _jsx("td", { children: submission.sourceIp })] }), formSubmissionRows({ data: submission.data, answerColumns }, { unknownFieldLabel: t("Unknown field") }).map(({ key, label, value }) => (_jsxs("tr", { children: [_jsx("th", { className: "jini-submission-field-label", children: label }), _jsx("td", { children: value })] }, key)))] }) }) }), _jsx("button", { type: "button", className: "btn-danger", disabled: deleting, onClick: requestDelete, ...agentHandle({ handle: "form-submission-delete" }, {
|
|
26
|
+
role: "button",
|
|
27
|
+
label: "Move this submission to the trash. Opens a confirmation dialog first.",
|
|
28
|
+
}), children: t("Delete submission") }), _jsx(ConfirmDialog, { open: confirmOpen, agentHandle: "form-submission-delete-confirm", title: t("Move to trash?"), body: _jsx("p", { children: t("It will disappear from this list. You can restore it from the Trash.") }), confirmLabel: t("Move to trash"), destructive: true, pending: deleting, onConfirm: confirmDelete, onCancel: cancelDelete })] }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=FormSubmissionDetail.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FormAnswerColumn } from '../../html-rules.js';
|
|
2
|
+
import { useWiredFormSubmissions } from '../hooks/use-form-submissions.hooks.js';
|
|
3
|
+
export interface FormSubmissionsProps {
|
|
4
|
+
formId: string;
|
|
5
|
+
/** Dependency injection seam for tests — see `PostsProps.usePostsHook` for the convention. */
|
|
6
|
+
useFormSubmissionsHook?: typeof useWiredFormSubmissions;
|
|
7
|
+
/** Translator closure — see `FormEditor()`'s own `t`. */
|
|
8
|
+
t: (key: string) => string;
|
|
9
|
+
answerColumns?: FormAnswerColumn[];
|
|
10
|
+
}
|
|
11
|
+
export declare function FormSubmissions({ formId, useFormSubmissionsHook, t, answerColumns }: FormSubmissionsProps, _optional?: Record<string, never>): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=FormSubmissions.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useSubmissionsView } from "../hooks/forms-view.hooks.js";
|
|
3
|
+
import { DataTable } from '../../../react/components/DataTable.js';
|
|
4
|
+
import { agentHandle } from '@jini-ai/agentic';
|
|
5
|
+
import { useWiredFormSubmissions } from '../hooks/use-form-submissions.hooks.js';
|
|
6
|
+
import { useFormSubmissionDate } from '../hooks/use-form-submission-date.hooks.js';
|
|
7
|
+
import { FormSubmissionDetail } from "./FormSubmissionDetail.js";
|
|
8
|
+
import { FormSubmissionDate } from "./FormSubmissionDate.js";
|
|
9
|
+
export function FormSubmissions({ formId, useFormSubmissionsHook = useWiredFormSubmissions, t, answerColumns = [] }, _optional = {}) {
|
|
10
|
+
const formatDate = useFormSubmissionDate({});
|
|
11
|
+
const controller = useFormSubmissionsHook({ formId });
|
|
12
|
+
const { submissions, nextCursor, error, selectedId, loadingMore } = controller;
|
|
13
|
+
const { rows, back, loadMore } = useSubmissionsView({ controller });
|
|
14
|
+
if (selectedId) {
|
|
15
|
+
return (_jsx(FormSubmissionDetail, { formId: formId, submissionId: selectedId, onBack: back, onDeleted: back, t: t, answerColumns: answerColumns }));
|
|
16
|
+
}
|
|
17
|
+
if (error && !submissions)
|
|
18
|
+
return _jsx("div", { className: "notice error", children: error });
|
|
19
|
+
if (!submissions)
|
|
20
|
+
return _jsx("div", { className: "notice", children: t("Loading submissions…") });
|
|
21
|
+
if (submissions.length === 0)
|
|
22
|
+
return _jsx("div", { className: "empty-state", children: t("No submissions yet.") });
|
|
23
|
+
// Submission ids are stable and unique, so they're what disambiguates one row's "View" button
|
|
24
|
+
// from another's — same reasoning as every other list on this workstream. Not `useMemo`d:
|
|
25
|
+
// computed after the three early returns above, so a `useMemo` here would need hoisting above
|
|
26
|
+
// them to keep hook order stable across renders — same constraint `Media.tsx` documents for its
|
|
27
|
+
// own post-early-return computation. `submissions` grows only on an explicit "Load more" click
|
|
28
|
+
// (`use-form-submissions.hooks.ts`'s cursor-append), so this O(n) pass tracks real data changes,
|
|
29
|
+
// not incidental re-renders.
|
|
30
|
+
return (_jsxs("div", { children: [error ? _jsx("div", { className: "notice error", children: error }) : null, _jsx(DataTable, { rows: rows, rowKey: (s) => s.id, columns: [
|
|
31
|
+
{ key: "submitted-at", header: t("Submitted at"), cell: (s) => _jsx(FormSubmissionDate, { date: formatDate({ iso: s.submittedAt }) }) },
|
|
32
|
+
{ key: "source-ip", header: t("Source IP"), cell: (s) => s.sourceIp },
|
|
33
|
+
...answerColumns,
|
|
34
|
+
{
|
|
35
|
+
key: "view",
|
|
36
|
+
cell: (s, index) => (_jsx("button", { type: "button", onClick: s.view, ...agentHandle({ handle: s.handle }, {
|
|
37
|
+
role: "button",
|
|
38
|
+
label: "Open this submission's full details",
|
|
39
|
+
}), children: t("View") })),
|
|
40
|
+
},
|
|
41
|
+
] }), nextCursor ? (_jsx("button", { type: "button", className: "btn-secondary", disabled: loadingMore, onClick: loadMore, ...agentHandle({ handle: "form-submissions-load-more" }, {
|
|
42
|
+
role: "button",
|
|
43
|
+
label: "Load the next page of submissions",
|
|
44
|
+
}), children: loadingMore ? t("Loading…") : t("Load more") })) : null] }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=FormSubmissions.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
2
|
+
import type { AdminFormsPort, FormsTrashPort, FormsEventsPort, FormsNavigationPort } from '../../ports.js';
|
|
3
|
+
import type { FormsTranslator } from '../../models.js';
|
|
4
|
+
export interface FormsPorts {
|
|
5
|
+
readonly formsApi: AdminFormsPort;
|
|
6
|
+
readonly formsTrash: FormsTrashPort;
|
|
7
|
+
readonly formsEvents?: FormsEventsPort;
|
|
8
|
+
readonly formsNavigation?: FormsNavigationPort;
|
|
9
|
+
}
|
|
10
|
+
export interface FormsReactOptions {
|
|
11
|
+
t?: FormsTranslator;
|
|
12
|
+
locale?: string;
|
|
13
|
+
adminBase?: string;
|
|
14
|
+
clipboard?: {
|
|
15
|
+
writeText(text: string): Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
headerActions?: ReactNode;
|
|
18
|
+
slots?: {
|
|
19
|
+
RecipientLabel?: ComponentType<{
|
|
20
|
+
count: number;
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare const FormsPortsContext: import("react").Context<FormsPorts | null>;
|
|
25
|
+
export declare const FormsOptionsContext: import("react").Context<FormsReactOptions>;
|
|
26
|
+
export declare function useFormsPorts(_required?: Record<string, never>, _optional?: {}): FormsPorts;
|
|
27
|
+
export declare function useFormsOptions(_required?: Record<string, never>, _optional?: {}): {
|
|
28
|
+
t: FormsTranslator;
|
|
29
|
+
locale: string;
|
|
30
|
+
adminBase: string;
|
|
31
|
+
clipboard?: {
|
|
32
|
+
writeText(text: string): Promise<void>;
|
|
33
|
+
};
|
|
34
|
+
headerActions?: ReactNode;
|
|
35
|
+
slots?: {
|
|
36
|
+
RecipientLabel?: ComponentType<{
|
|
37
|
+
count: number;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=FormsPorts.hooks.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import { AdminConfigError } from '../../../core/module/create-admin.js';
|
|
3
|
+
import { translateForms } from '../../messages.en.js';
|
|
4
|
+
export const FormsPortsContext = createContext(null);
|
|
5
|
+
export const FormsOptionsContext = createContext({});
|
|
6
|
+
export function useFormsPorts(_required = {}, _optional = {}) {
|
|
7
|
+
const ports = useContext(FormsPortsContext);
|
|
8
|
+
if (!ports)
|
|
9
|
+
throw new AdminConfigError({ issues: ['React scope unavailable: forms'] });
|
|
10
|
+
return ports;
|
|
11
|
+
}
|
|
12
|
+
export function useFormsOptions(_required = {}, _optional = {}) {
|
|
13
|
+
const options = useContext(FormsOptionsContext);
|
|
14
|
+
return { ...options, t: options.t ?? translateForms, locale: options.locale ?? 'en', adminBase: options.adminBase ?? '/admin' };
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=FormsPorts.hooks.js.map
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { ChangeEvent, MutableRefObject } from 'react';
|
|
2
|
+
import { type FormDateLine } from '../../rules.js';
|
|
3
|
+
import type { FormFieldsEditorController } from './use-form-fields-editor.hooks.js';
|
|
4
|
+
import type { FieldAttributesDialogController } from './use-field-attributes-dialog.hooks.js';
|
|
5
|
+
import type { FormSubmissionsController } from './use-form-submissions.hooks.js';
|
|
6
|
+
import type { FormEditorFieldsBodyProps } from '../components/FormEditorFieldsBody.js';
|
|
7
|
+
import type { AdminFormDefinition, AdminFormField } from '../../models.js';
|
|
8
|
+
/** Publication actions keep their original DOM at the host slot. */
|
|
9
|
+
export declare function useFormsListView({ forms, t, formatFormDates, toggleStatus, setPendingDelete }: {
|
|
10
|
+
forms: AdminFormDefinition[] | null;
|
|
11
|
+
t: (key: string) => string;
|
|
12
|
+
formatFormDates: (form: AdminFormDefinition) => FormDateLine[];
|
|
13
|
+
toggleStatus: (form: AdminFormDefinition) => Promise<void>;
|
|
14
|
+
setPendingDelete: (form: AdminFormDefinition | null) => void;
|
|
15
|
+
}, _optional?: {}): {
|
|
16
|
+
rows: {
|
|
17
|
+
rowHandle: string;
|
|
18
|
+
dates: FormDateLine[];
|
|
19
|
+
menuLabel: string;
|
|
20
|
+
menuItems: import("../../../react/index.js").RowMenuItem[];
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
html?: string | undefined;
|
|
24
|
+
status: import("../../../core/index.js").FormDefinitionStatus;
|
|
25
|
+
mode?: "builder" | "html" | undefined;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
slug: string;
|
|
29
|
+
workspaceId?: string;
|
|
30
|
+
fields: AdminFormField[];
|
|
31
|
+
notify: import("../../models.js").AdminFormNotify;
|
|
32
|
+
}[];
|
|
33
|
+
cancelDelete: () => void;
|
|
34
|
+
headerActions: import("react").ReactNode;
|
|
35
|
+
};
|
|
36
|
+
/** Bind every field-row callback and focus ref outside the markup. */
|
|
37
|
+
export declare function useFormFieldsView({ fields, existingFieldIds, controller }: {
|
|
38
|
+
fields: AdminFormField[];
|
|
39
|
+
existingFieldIds: string[];
|
|
40
|
+
controller: FormFieldsEditorController;
|
|
41
|
+
}, _optional?: {}): {
|
|
42
|
+
editingField: AdminFormField | null;
|
|
43
|
+
saveAttributes: (patch: Partial<AdminFormField>) => void;
|
|
44
|
+
rows: {
|
|
45
|
+
field: AdminFormField;
|
|
46
|
+
index: number;
|
|
47
|
+
base: string;
|
|
48
|
+
isExisting: boolean;
|
|
49
|
+
displayName: string;
|
|
50
|
+
onId: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
51
|
+
onLabel: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
52
|
+
onType: (e: ChangeEvent<HTMLSelectElement>) => void;
|
|
53
|
+
onRequired: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
54
|
+
onMaxLength: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
55
|
+
ref: (el: HTMLButtonElement | null) => void;
|
|
56
|
+
onAttributes: () => void;
|
|
57
|
+
onRemove: () => void;
|
|
58
|
+
}[];
|
|
59
|
+
};
|
|
60
|
+
export declare function useFieldAttributesView({ field, fieldIndex, controller, onCancel }: {
|
|
61
|
+
field: AdminFormField;
|
|
62
|
+
fieldIndex: number;
|
|
63
|
+
controller: FieldAttributesDialogController;
|
|
64
|
+
onCancel: () => void;
|
|
65
|
+
}, _optional?: {}): {
|
|
66
|
+
displayName: string;
|
|
67
|
+
onClose: () => void;
|
|
68
|
+
onClassName: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
69
|
+
rows: {
|
|
70
|
+
handle: string;
|
|
71
|
+
onName: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
72
|
+
onValue: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
73
|
+
onRemove: () => void;
|
|
74
|
+
_rowId: number;
|
|
75
|
+
name: string;
|
|
76
|
+
value: string;
|
|
77
|
+
}[];
|
|
78
|
+
};
|
|
79
|
+
export declare function useSubmissionsView({ controller }: {
|
|
80
|
+
controller: FormSubmissionsController;
|
|
81
|
+
}, _optional?: {}): {
|
|
82
|
+
back: () => void;
|
|
83
|
+
loadMore: () => void;
|
|
84
|
+
rows: {
|
|
85
|
+
handle: string;
|
|
86
|
+
view: () => void;
|
|
87
|
+
id: string;
|
|
88
|
+
status?: "active" | "trash";
|
|
89
|
+
formDefinitionId: string;
|
|
90
|
+
sourceIp: string;
|
|
91
|
+
submittedAt: string;
|
|
92
|
+
workspaceId?: string;
|
|
93
|
+
data: Record<string, string | boolean>;
|
|
94
|
+
}[];
|
|
95
|
+
};
|
|
96
|
+
export declare function useFormFieldsBodyView(props: FormEditorFieldsBodyProps, _optional?: {}): {
|
|
97
|
+
onName: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
98
|
+
onSlug: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
99
|
+
onHtml: (e: ChangeEvent<HTMLTextAreaElement>) => void;
|
|
100
|
+
onBuilder: () => void;
|
|
101
|
+
onHtmlMode: () => void;
|
|
102
|
+
};
|
|
103
|
+
export declare function useFormTabStripView({ onTabChange, tabRefs }: {
|
|
104
|
+
onTabChange: (tab: 'fields' | 'submissions') => void;
|
|
105
|
+
tabRefs: MutableRefObject<Array<HTMLButtonElement | null>>;
|
|
106
|
+
}, _optional?: {}): ({
|
|
107
|
+
ref: (el: HTMLButtonElement | null) => void;
|
|
108
|
+
onClick: () => void;
|
|
109
|
+
id: "fields";
|
|
110
|
+
label: "Fields";
|
|
111
|
+
} | {
|
|
112
|
+
ref: (el: HTMLButtonElement | null) => void;
|
|
113
|
+
onClick: () => void;
|
|
114
|
+
id: "submissions";
|
|
115
|
+
label: "Submissions";
|
|
116
|
+
})[];
|
|
117
|
+
//# sourceMappingURL=forms-view.hooks.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { buildAgentListHandles } from '@jini-ai/agentic';
|
|
2
|
+
import { fieldDisplayName, formRowMenuItems, FORM_TABS } from '../../rules.js';
|
|
3
|
+
import { useFormsOptions, FormsPortsContext } from './FormsPorts.hooks.js';
|
|
4
|
+
import { useContext } from 'react';
|
|
5
|
+
/** Publication actions keep their original DOM at the host slot. */
|
|
6
|
+
export function useFormsListView({ forms, t, formatFormDates, toggleStatus, setPendingDelete }, _optional = {}) {
|
|
7
|
+
const ports = useContext(FormsPortsContext);
|
|
8
|
+
const { headerActions, adminBase } = useFormsOptions();
|
|
9
|
+
const rowHandles = buildAgentListHandles({ prefix: 'forms-row', ids: (forms ?? []).map(form => form.id) });
|
|
10
|
+
const onEdit = (form) => {
|
|
11
|
+
if (!ports?.formsNavigation)
|
|
12
|
+
throw new Error('Missing forms navigation port');
|
|
13
|
+
ports.formsNavigation.navigate({ base: adminBase, routePath: `/forms/${form.slug}` });
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
rows: (forms ?? []).map((form, index) => ({ ...form, rowHandle: rowHandles[index], dates: formatFormDates(form),
|
|
17
|
+
menuLabel: t('Actions for form "{name}"').replace('{name}', form.name),
|
|
18
|
+
menuItems: formRowMenuItems({ form, handlers: { onEdit, onToggleStatus: form => { void toggleStatus(form); }, onDelete: setPendingDelete }, t }), })),
|
|
19
|
+
cancelDelete: () => setPendingDelete(null), headerActions,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Bind every field-row callback and focus ref outside the markup. */
|
|
23
|
+
export function useFormFieldsView({ fields, existingFieldIds, controller }, _optional = {}) {
|
|
24
|
+
const handles = buildAgentListHandles({ prefix: 'form-field', ids: fields.map(field => field.id) });
|
|
25
|
+
const index = controller.editingAttrsIndex;
|
|
26
|
+
return {
|
|
27
|
+
editingField: index === null ? null : fields[index] ?? null,
|
|
28
|
+
saveAttributes: (patch) => {
|
|
29
|
+
if (index === null)
|
|
30
|
+
return;
|
|
31
|
+
controller.updateField(index, patch);
|
|
32
|
+
controller.closeAttrsDialog();
|
|
33
|
+
},
|
|
34
|
+
rows: fields.map((field, index) => ({ field, index, base: handles[index], isExisting: existingFieldIds.includes(field.id), displayName: fieldDisplayName({ field, index }),
|
|
35
|
+
onId: (e) => controller.updateField(index, { id: e.target.value }),
|
|
36
|
+
onLabel: (e) => controller.updateField(index, { label: e.target.value }),
|
|
37
|
+
onType: (e) => controller.updateField(index, { type: e.target.value }),
|
|
38
|
+
onRequired: (e) => controller.updateField(index, { required: e.target.checked }),
|
|
39
|
+
onMaxLength: (e) => controller.updateField(index, { maxLength: e.target.value ? Number(e.target.value) : null }),
|
|
40
|
+
ref: (el) => { controller.kebabRefs.current[index] = el; },
|
|
41
|
+
onAttributes: () => controller.openAttrsDialog(index), onRemove: () => controller.removeField(index), })),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function useFieldAttributesView({ field, fieldIndex, controller, onCancel }, _optional = {}) {
|
|
45
|
+
const handles = buildAgentListHandles({ prefix: 'form-field-attrs-row', ids: controller.rows.map(row => String(row._rowId)) });
|
|
46
|
+
return {
|
|
47
|
+
displayName: fieldDisplayName({ field, index: fieldIndex }), onClose: () => onCancel(),
|
|
48
|
+
onClassName: (e) => controller.setClassName(e.target.value),
|
|
49
|
+
rows: controller.rows.map((row, index) => ({ ...row, handle: handles[index],
|
|
50
|
+
onName: (e) => controller.updateRow(row._rowId, { name: e.target.value }),
|
|
51
|
+
onValue: (e) => controller.updateRow(row._rowId, { value: e.target.value }),
|
|
52
|
+
onRemove: () => controller.removeRow(row._rowId), })),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function useSubmissionsView({ controller }, _optional = {}) {
|
|
56
|
+
const handles = buildAgentListHandles({ prefix: 'form-submission-view', ids: (controller.submissions ?? []).map(submission => submission.id) });
|
|
57
|
+
return {
|
|
58
|
+
// Successful removal invalidates its own query; this callback only exits the detail view.
|
|
59
|
+
back: () => controller.setSelectedId(null),
|
|
60
|
+
loadMore: () => { if (controller.nextCursor)
|
|
61
|
+
controller.load(controller.nextCursor); },
|
|
62
|
+
rows: (controller.submissions ?? []).map((submission, index) => ({ ...submission, handle: handles[index], view: () => controller.setSelectedId(submission.id) })),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function useFormFieldsBodyView(props, _optional = {}) {
|
|
66
|
+
return {
|
|
67
|
+
onName: (e) => props.onNameChange(e.target.value),
|
|
68
|
+
onSlug: (e) => props.onSlugChange(e.target.value),
|
|
69
|
+
onHtml: (e) => props.onHtmlChange(e.target.value),
|
|
70
|
+
onBuilder: () => props.onModeChange('builder'), onHtmlMode: () => props.onModeChange('html'),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function useFormTabStripView({ onTabChange, tabRefs }, _optional = {}) {
|
|
74
|
+
return FORM_TABS.map((tab, index) => ({ ...tab,
|
|
75
|
+
ref: (el) => { tabRefs.current[index] = el; },
|
|
76
|
+
onClick: () => onTabChange(tab.id), }));
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=forms-view.hooks.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AdminFormField } from "../../models.js";
|
|
2
|
+
import { type AttrRow } from "../../rules.js";
|
|
3
|
+
/**
|
|
4
|
+
* @file `FieldAttributesDialog`'s own state and submit action (per-field CSS classes + HTML
|
|
5
|
+
* attributes), so the dialog in `FormEditor.tsx` is only markup.
|
|
6
|
+
*
|
|
7
|
+
* Moved from the host — same state, same validation, same error strings. Draft-row editing and the
|
|
8
|
+
* validate/shape step now live in `rules.ts` (`updateAttrRow`/`removeAttrRow`/`addAttrRow`,
|
|
9
|
+
* `buildFieldAttributesPatch`).
|
|
10
|
+
*
|
|
11
|
+
* Naming follows `hooks/use-settings-slice.hooks.ts`: `use-<thing>.hooks.ts`. Feature-local because
|
|
12
|
+
* nothing outside `features/forms` needs it. The former Escape helper was likewise feature-local
|
|
13
|
+
* because only this dialog needed it; Jini now owns that shared modal behavior, so the helper
|
|
14
|
+
* and its document subscription are superseded rather than promoted to another local owner.
|
|
15
|
+
*/
|
|
16
|
+
export interface FieldAttributesDialogController {
|
|
17
|
+
className: string;
|
|
18
|
+
setClassName: (value: string) => void;
|
|
19
|
+
rows: AttrRow[];
|
|
20
|
+
updateRow: (rowId: number, patch: Partial<AttrRow>) => void;
|
|
21
|
+
removeRow: (rowId: number) => void;
|
|
22
|
+
addRow: () => void;
|
|
23
|
+
error: string | null;
|
|
24
|
+
submit: (e: React.FormEvent) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare function useFieldAttributesDialog(props: {
|
|
27
|
+
field: AdminFormField;
|
|
28
|
+
onSave: (patch: Partial<AdminFormField>) => void;
|
|
29
|
+
onCancel: () => void;
|
|
30
|
+
}, _optional?: Record<string, never>): FieldAttributesDialogController;
|
|
31
|
+
//# sourceMappingURL=use-field-attributes-dialog.hooks.d.ts.map
|