includio-cms 0.24.1 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +57 -4
- package/CHANGELOG.md +53 -0
- package/DOCS.md +1 -1
- package/README.md +2 -0
- package/ROADMAP.md +6 -0
- package/dist/admin/client/account/lang.d.ts +1 -0
- package/dist/admin/client/account/lang.js +4 -2
- package/dist/admin/client/account/profile-section.svelte +2 -2
- package/dist/admin/client/account/security-section.svelte +27 -4
- package/dist/admin/client/account/sessions-section.svelte +1 -1
- package/dist/admin/client/admin/admin-after-login-layout-content.svelte +1 -1
- package/dist/admin/client/admin/dashboard-page.svelte +34 -10
- package/dist/admin/client/collection/bulk-actions-bar.svelte +86 -44
- package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +3 -1
- package/dist/admin/client/collection/collection-entries.svelte +52 -36
- package/dist/admin/client/collection/collection-entries.svelte.d.ts +3 -0
- package/dist/admin/client/collection/collection.svelte +28 -14
- package/dist/admin/client/collection/collection.svelte.d.ts +3 -0
- package/dist/admin/client/collection/data-table.svelte +279 -130
- package/dist/admin/client/collection/data-table.svelte.d.ts +11 -0
- package/dist/admin/client/collection/date-cell.svelte +4 -4
- package/dist/admin/client/collection/row-actions.svelte +2 -1
- package/dist/admin/client/collection/sortable-header.svelte +33 -9
- package/dist/admin/client/collection/state-display.svelte +102 -0
- package/dist/admin/client/collection/state-display.svelte.d.ts +12 -0
- package/dist/admin/client/collection/status-badge.svelte +99 -11
- package/dist/admin/client/collection/status-badge.svelte.d.ts +15 -1
- package/dist/admin/client/collection/table-pagination.svelte +21 -6
- package/dist/admin/client/collection/table-toolbar.svelte +105 -80
- package/dist/admin/client/collection/table-toolbar.svelte.d.ts +11 -8
- package/dist/admin/client/entry/entry-form.svelte +36 -11
- package/dist/admin/client/entry/entry-form.svelte.d.ts +1 -0
- package/dist/admin/client/entry/entry-header.svelte +22 -15
- package/dist/admin/client/entry/entry-header.svelte.d.ts +1 -0
- package/dist/admin/client/entry/entry.svelte +269 -165
- package/dist/admin/client/entry/header/a11y-header-badge.svelte +47 -0
- package/dist/admin/client/entry/header/a11y-header-badge.svelte.d.ts +8 -0
- package/dist/admin/client/entry/header/publish-panel.svelte +69 -13
- package/dist/admin/client/entry/header/save-indicator.svelte +57 -28
- package/dist/admin/client/entry/header/save-indicator.svelte.d.ts +1 -0
- package/dist/admin/client/entry/header/status-badge.svelte +60 -15
- package/dist/admin/client/entry/header/status-badge.svelte.d.ts +1 -2
- package/dist/admin/client/entry/header/version-history-sheet.svelte +1 -1
- package/dist/admin/client/entry/hybrid/hybrid-layout.svelte +74 -23
- package/dist/admin/client/entry/hybrid/hybrid-preview.svelte +1 -1
- package/dist/admin/client/entry/utils.d.ts +14 -0
- package/dist/admin/client/entry/utils.js +28 -0
- package/dist/admin/client/form/form-submission/form-submission.svelte +2 -2
- package/dist/admin/client/form/form-submissions.svelte +143 -194
- package/dist/admin/client/form/form-submissions.svelte.d.ts +2 -0
- package/dist/admin/client/login/lang.d.ts +3 -0
- package/dist/admin/client/login/lang.js +10 -4
- package/dist/admin/client/login/login-form.svelte +8 -1
- package/dist/admin/client/login/reset-password-page.svelte +24 -3
- package/dist/admin/client/login/schema.d.ts +14 -2
- package/dist/admin/client/login/schema.js +19 -8
- package/dist/admin/client/maintenance/maintenance-page.svelte +16 -17
- package/dist/admin/client/media/media-page.svelte +1 -1
- package/dist/admin/client/shop/coupon-edit-page.svelte +117 -13
- package/dist/admin/client/shop/coupon-form.svelte +282 -138
- package/dist/admin/client/shop/coupon-form.svelte.d.ts +1 -9
- package/dist/admin/client/shop/coupon-new-page.svelte +40 -10
- package/dist/admin/client/shop/coupon-new-page.svelte.d.ts +2 -17
- package/dist/admin/client/shop/coupon-schema.d.ts +28 -0
- package/dist/admin/client/shop/coupon-schema.js +53 -0
- package/dist/admin/client/shop/coupons-list-page.svelte +262 -118
- package/dist/admin/client/shop/coupons-list-page.svelte.d.ts +16 -1
- package/dist/admin/client/shop/shipping-method-edit-page.svelte +108 -59
- package/dist/admin/client/shop/shipping-method-form.svelte +36 -9
- package/dist/admin/client/shop/shipping-method-new-page.svelte +44 -13
- package/dist/admin/client/shop/shipping-methods-list-page.svelte +101 -59
- package/dist/admin/client/shop/shop-order-detail-page.svelte +113 -84
- package/dist/admin/client/shop/shop-orders-list-page.svelte +302 -152
- package/dist/admin/client/shop/shop-orders-list-page.svelte.d.ts +18 -1
- package/dist/admin/client/shop/shop-products-list-page.svelte +355 -118
- package/dist/admin/client/shop/shop-products-list-page.svelte.d.ts +19 -1
- package/dist/admin/client/users/accept-invite-page.svelte +24 -3
- package/dist/admin/client/users/create-user-dialog.svelte +3 -8
- package/dist/admin/client/users/lang.d.ts +2 -0
- package/dist/admin/client/users/lang.js +4 -0
- package/dist/admin/client/users/pending-invitations.svelte +2 -9
- package/dist/admin/client/users/user-name-cell.svelte +20 -0
- package/dist/admin/client/users/user-name-cell.svelte.d.ts +9 -0
- package/dist/admin/client/users/user-role-badge.svelte +16 -0
- package/dist/admin/client/users/user-role-badge.svelte.d.ts +7 -0
- package/dist/admin/client/users/user-row-actions.svelte +72 -0
- package/dist/admin/client/users/user-row-actions.svelte.d.ts +20 -0
- package/dist/admin/client/users/user-sessions-sheet.svelte +2 -11
- package/dist/admin/client/users/users-page.svelte +283 -497
- package/dist/admin/client/users/users-page.svelte.d.ts +12 -1
- package/dist/admin/components/dashboard/form-submissions-widget.svelte +59 -74
- package/dist/admin/components/dashboard/recent-activity.svelte +17 -5
- package/dist/admin/components/dashboard/recent-entries.svelte +19 -7
- package/dist/admin/components/dialogs/confirmation-dialog.svelte +105 -0
- package/dist/admin/components/dialogs/confirmation-dialog.svelte.d.ts +13 -0
- package/dist/admin/components/fields/block-picker-modal.svelte +6 -0
- package/dist/admin/components/fields/blocks-field.svelte +46 -1
- package/dist/admin/components/fields/boolean-field.svelte +1 -1
- package/dist/admin/components/fields/field-renderer.svelte +23 -21
- package/dist/admin/components/fields/file-field.svelte +344 -30
- package/dist/admin/components/fields/media-field.svelte +16 -2
- package/dist/admin/components/fields/radio-field.svelte +22 -0
- package/dist/admin/components/fields/relation-field.svelte +123 -97
- package/dist/admin/components/fields/relation-picker-dialog.svelte +2 -2
- package/dist/admin/components/fields/seo-field.svelte +60 -30
- package/dist/admin/components/fields/shop-field.svelte +9 -4
- package/dist/admin/components/fields/simple-array-field.svelte +321 -151
- package/dist/admin/components/fields/simple-array-field.svelte.d.ts +3 -0
- package/dist/admin/components/fields/slug-field.svelte +146 -21
- package/dist/admin/components/fields/text-field-wrapper.svelte +37 -20
- package/dist/admin/components/fields/text-field.svelte +7 -2
- package/dist/admin/components/fields/url-field-wrapper.svelte +10 -0
- package/dist/admin/components/fields/url-field.svelte +36 -23
- package/dist/admin/components/forms/form-error-summary.svelte +143 -0
- package/dist/admin/components/forms/form-error-summary.svelte.d.ts +27 -0
- package/dist/admin/components/layout/app-sidebar.svelte +7 -2
- package/dist/admin/components/layout/detail-page-shell.svelte +71 -0
- package/dist/admin/components/layout/detail-page-shell.svelte.d.ts +24 -0
- package/dist/admin/components/layout/lang.d.ts +5 -0
- package/dist/admin/components/layout/lang.js +10 -0
- package/dist/admin/components/layout/layout-renderer.svelte +71 -2
- package/dist/admin/components/layout/layout-renderer.svelte.d.ts +1 -0
- package/dist/admin/components/layout/layout-tabs.svelte +172 -0
- package/dist/admin/components/layout/layout-tabs.svelte.d.ts +24 -0
- package/dist/admin/components/layout/nav-breadcrumbs.svelte +25 -7
- package/dist/admin/components/layout/nav-collections.svelte +23 -36
- package/dist/admin/components/layout/nav-forms.svelte +19 -35
- package/dist/admin/components/layout/nav-main.svelte +3 -28
- package/dist/admin/components/layout/nav-search.svelte +70 -2
- package/dist/admin/components/layout/nav-section.svelte +77 -0
- package/dist/admin/components/layout/nav-section.svelte.d.ts +22 -0
- package/dist/admin/components/layout/nav-shop.svelte +3 -27
- package/dist/admin/components/layout/nav-singletons.svelte +16 -28
- package/dist/admin/components/layout/page-header.stories.svelte +93 -0
- package/dist/admin/components/layout/page-header.stories.svelte.d.ts +27 -0
- package/dist/admin/components/layout/page-header.svelte +68 -0
- package/dist/admin/components/layout/page-header.svelte.d.ts +17 -0
- package/dist/admin/components/layout/site-header.svelte +9 -0
- package/dist/admin/components/layout/site-header.svelte.d.ts +2 -17
- package/dist/admin/components/media/file/file-name-input.svelte +6 -2
- package/dist/admin/components/media/file/file-preview.svelte +130 -17
- package/dist/admin/components/media/file-upload.svelte +16 -7
- package/dist/admin/components/media/file-upload.svelte.d.ts +1 -0
- package/dist/admin/components/media/files-list.svelte +153 -53
- package/dist/admin/components/media/files-list.svelte.d.ts +1 -0
- package/dist/admin/components/media/media-library.svelte +577 -198
- package/dist/admin/components/media/media-library.svelte.d.ts +4 -0
- package/dist/admin/components/media/media-selector.svelte +4 -2
- package/dist/admin/components/media/media-selector.svelte.d.ts +1 -0
- package/dist/admin/components/media/tag-sidebar.svelte +4 -4
- package/dist/admin/components/tiptap/FigureNodeView.svelte +10 -0
- package/dist/admin/components/tiptap/bubble-menu.svelte +104 -0
- package/dist/admin/components/tiptap/bubble-menu.svelte.d.ts +19 -0
- package/dist/admin/components/tiptap/content-editor.svelte +28 -24
- package/dist/admin/components/tiptap/editor-toolbar.svelte +7 -7
- package/dist/admin/components/tiptap/extensions.js +5 -1
- package/dist/admin/components/tiptap/image-dialog.svelte +5 -1
- package/dist/admin/components/tiptap/link-dialog.svelte +2 -0
- package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -20
- package/dist/admin/components/tiptap/video-dialog.svelte +1 -1
- package/dist/admin/i18n/errors.d.ts +140 -0
- package/dist/admin/i18n/errors.js +151 -0
- package/dist/admin/remote/entry.remote.d.ts +59 -4
- package/dist/admin/remote/entry.remote.js +239 -62
- package/dist/admin/remote/shop.remote.d.ts +37 -32
- package/dist/admin/remote/shop.remote.js +9 -2
- package/dist/admin/shared/password-generate.d.ts +6 -0
- package/dist/admin/shared/password-generate.js +40 -0
- package/dist/admin/shared/password-schema.d.ts +6 -0
- package/dist/admin/shared/password-schema.js +10 -3
- package/dist/admin/styles/admin.css +23 -6
- package/dist/admin/styles/tokens.md +244 -0
- package/dist/admin/utils/accordionActivation.d.ts +13 -0
- package/dist/admin/utils/accordionActivation.js +35 -0
- package/dist/admin/utils/entryLabel.d.ts +23 -0
- package/dist/admin/utils/entryLabel.js +51 -12
- package/dist/admin/utils/field-a11y.d.ts +29 -0
- package/dist/admin/utils/field-a11y.js +23 -0
- package/dist/admin/utils/fieldPathElement.d.ts +9 -0
- package/dist/admin/utils/fieldPathElement.js +18 -0
- package/dist/admin/utils/fileDisplay.d.ts +10 -0
- package/dist/admin/utils/fileDisplay.js +26 -0
- package/dist/admin/utils/flattenFormErrors.d.ts +19 -0
- package/dist/admin/utils/flattenFormErrors.js +102 -0
- package/dist/admin/utils/formatters.d.ts +12 -0
- package/dist/admin/utils/{formatDate.js → formatters.js} +23 -2
- package/dist/admin/utils/scrollWithin.d.ts +9 -0
- package/dist/admin/utils/scrollWithin.js +32 -0
- package/dist/admin/utils/tabActivation.d.ts +12 -0
- package/dist/admin/utils/tabActivation.js +24 -0
- package/dist/cms/runtime/schema.d.ts +1 -0
- package/dist/cms/runtime/schema.js +1 -0
- package/dist/cms/runtime/types.d.ts +80 -7
- package/dist/components/ui/accordion/accordion-content.svelte +17 -3
- package/dist/components/ui/accordion/accordion.stories.svelte +21 -1
- package/dist/components/ui/alert/alert.stories.svelte +14 -0
- package/dist/components/ui/alert-dialog/alert-dialog.stories.svelte +45 -0
- package/dist/components/ui/alert-dialog/alert-dialog.stories.svelte.d.ts +27 -0
- package/dist/components/ui/avatar/avatar.stories.svelte +27 -0
- package/dist/components/ui/badge/badge.stories.svelte +15 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +47 -0
- package/dist/components/ui/breadcrumb/breadcrumb.svelte +1 -1
- package/dist/components/ui/button/button.stories.svelte +53 -6
- package/dist/components/ui/button/button.svelte +39 -5
- package/dist/components/ui/button/button.svelte.d.ts +4 -0
- package/dist/components/ui/button-group/button-group.stories.svelte +44 -0
- package/dist/components/ui/button-group/button-group.stories.svelte.d.ts +27 -0
- package/dist/components/ui/calendar/calendar.stories.svelte +36 -0
- package/dist/components/ui/calendar/calendar.stories.svelte.d.ts +27 -0
- package/dist/components/ui/card/card.stories.svelte +7 -0
- package/dist/components/ui/carousel/carousel.stories.svelte +43 -0
- package/dist/components/ui/carousel/carousel.stories.svelte.d.ts +27 -0
- package/dist/components/ui/checkbox/checkbox.stories.svelte +67 -0
- package/dist/components/ui/checkbox/checkbox.stories.svelte.d.ts +27 -0
- package/dist/components/ui/checkbox/checkbox.svelte +3 -3
- package/dist/components/ui/command/command.stories.svelte +18 -0
- package/dist/components/ui/data-table/data-table.stories.svelte +61 -0
- package/dist/components/ui/data-table/data-table.stories.svelte.d.ts +18 -0
- package/dist/components/ui/dialog/dialog-content.svelte +5 -0
- package/dist/components/ui/dialog/dialog-content.svelte.d.ts +2 -0
- package/dist/components/ui/dialog/dialog.stories.svelte +35 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.stories.svelte +74 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.stories.svelte.d.ts +27 -0
- package/dist/components/ui/field/field-context.svelte.d.ts +22 -0
- package/dist/components/ui/field/field-context.svelte.js +9 -0
- package/dist/components/ui/field/field-control.svelte +18 -0
- package/dist/components/ui/field/field-control.svelte.d.ts +8 -0
- package/dist/components/ui/field/field-description.svelte +12 -0
- package/dist/components/ui/field/field-error.svelte +14 -6
- package/dist/components/ui/field/field-label.svelte +10 -0
- package/dist/components/ui/field/field.stories.svelte +95 -9
- package/dist/components/ui/field/field.svelte +57 -0
- package/dist/components/ui/field/field.svelte.d.ts +2 -0
- package/dist/components/ui/field/index.d.ts +3 -1
- package/dist/components/ui/field/index.js +4 -2
- package/dist/components/ui/form/form-field-errors.svelte +1 -1
- package/dist/components/ui/form/form.stories.svelte +25 -0
- package/dist/components/ui/form/form.stories.svelte.d.ts +26 -0
- package/dist/components/ui/input/input.stories.svelte +26 -0
- package/dist/components/ui/input-group/input-group-input.svelte.d.ts +1 -1
- package/dist/components/ui/input-group/input-group.stories.svelte +43 -0
- package/dist/components/ui/input-group/input-group.stories.svelte.d.ts +27 -0
- package/dist/components/ui/item/item.stories.svelte +61 -0
- package/dist/components/ui/item/item.stories.svelte.d.ts +27 -0
- package/dist/components/ui/label/label.stories.svelte +7 -0
- package/dist/components/ui/live-region/index.d.ts +1 -0
- package/dist/components/ui/live-region/index.js +1 -0
- package/dist/components/ui/live-region/live-region-demo.svelte +32 -0
- package/dist/components/ui/live-region/live-region-demo.svelte.d.ts +7 -0
- package/dist/components/ui/live-region/live-region.stories.svelte +23 -0
- package/dist/components/ui/live-region/live-region.stories.svelte.d.ts +26 -0
- package/dist/components/ui/live-region/live-region.svelte +12 -0
- package/dist/components/ui/live-region/live-region.svelte.d.ts +8 -0
- package/dist/components/ui/popover/popover.stories.svelte +34 -0
- package/dist/components/ui/radio-group/radio-group.stories.svelte +58 -0
- package/dist/components/ui/radio-group/radio-group.stories.svelte.d.ts +27 -0
- package/dist/components/ui/resizable/resizable.stories.svelte +56 -0
- package/dist/components/ui/resizable/resizable.stories.svelte.d.ts +27 -0
- package/dist/components/ui/select/select.stories.svelte +49 -0
- package/dist/components/ui/separator/separator.stories.svelte +18 -0
- package/dist/components/ui/sheet/sheet.stories.svelte +34 -0
- package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-menu-button.svelte +1 -0
- package/dist/components/ui/sidebar/sidebar-trigger.svelte +1 -1
- package/dist/components/ui/sidebar/sidebar.stories.svelte +72 -0
- package/dist/components/ui/sidebar/sidebar.stories.svelte.d.ts +27 -0
- package/dist/components/ui/skeleton/skeleton.stories.svelte +39 -0
- package/dist/components/ui/skeleton/skeleton.stories.svelte.d.ts +27 -0
- package/dist/components/ui/skeleton/skeleton.svelte +6 -0
- package/dist/components/ui/sonner/index.d.ts +1 -1
- package/dist/components/ui/sonner/index.js +1 -1
- package/dist/components/ui/sonner/sonner.stories.svelte +7 -0
- package/dist/components/ui/sonner/sonner.svelte +17 -1
- package/dist/components/ui/sonner/sonner.svelte.d.ts +6 -0
- package/dist/components/ui/spinner/spinner.stories.svelte +30 -0
- package/dist/components/ui/spinner/spinner.stories.svelte.d.ts +27 -0
- package/dist/components/ui/switch/switch.stories.svelte +56 -0
- package/dist/components/ui/switch/switch.stories.svelte.d.ts +27 -0
- package/dist/components/ui/table/table-cell.svelte +1 -1
- package/dist/components/ui/table/table-head.svelte +1 -1
- package/dist/components/ui/table/table.stories.svelte +68 -0
- package/dist/components/ui/table/table.stories.svelte.d.ts +27 -0
- package/dist/components/ui/table/table.svelte +1 -1
- package/dist/components/ui/tabs/tabs.stories.svelte +48 -0
- package/dist/components/ui/tabs/tabs.stories.svelte.d.ts +27 -0
- package/dist/components/ui/textarea/textarea.stories.svelte +21 -0
- package/dist/components/ui/toggle/toggle.stories.svelte +23 -0
- package/dist/components/ui/toggle-group/toggle-group.stories.svelte +43 -0
- package/dist/components/ui/tooltip/tooltip.stories.svelte +46 -6
- package/dist/core/fields/fieldSchemaToTs.d.ts +7 -0
- package/dist/core/fields/fieldSchemaToTs.js +234 -90
- package/dist/core/fields/layoutUtils.d.ts +4 -1
- package/dist/core/fields/layoutUtils.js +41 -4
- package/dist/core/fields/resolveSeo.d.ts +70 -0
- package/dist/core/fields/resolveSeo.js +88 -0
- package/dist/core/fields/seoFieldDescriptor.d.ts +43 -0
- package/dist/core/fields/seoFieldDescriptor.js +74 -0
- package/dist/core/fields/slugPath.d.ts +13 -0
- package/dist/core/fields/slugPath.js +32 -0
- package/dist/core/fields/urlUtils.d.ts +8 -0
- package/dist/core/fields/urlUtils.js +27 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/server/entries/operations/create.js +13 -0
- package/dist/core/server/entries/operations/get.d.ts +7 -0
- package/dist/core/server/entries/operations/get.js +10 -6
- package/dist/core/server/entries/operations/slugUniqueness.d.ts +37 -0
- package/dist/core/server/entries/operations/slugUniqueness.js +116 -0
- package/dist/core/server/entries/operations/update.d.ts +6 -1
- package/dist/core/server/entries/operations/update.js +24 -1
- package/dist/core/server/fields/slugResolver.d.ts +3 -13
- package/dist/core/server/fields/slugResolver.js +8 -37
- package/dist/core/server/generator/fields.js +10 -17
- package/dist/core/server/generator/formFields.js +2 -1
- package/dist/core/server/generator/generator.js +4 -4
- package/dist/core/server/generator/utils.d.ts +1 -0
- package/dist/core/server/generator/utils.js +4 -0
- package/dist/paraglide/messages/_index.d.ts +3 -36
- package/dist/paraglide/messages/_index.js +3 -71
- package/dist/paraglide/messages/hello_world.d.ts +5 -0
- package/dist/paraglide/messages/hello_world.js +33 -0
- package/dist/paraglide/messages/login_hello.d.ts +16 -0
- package/dist/paraglide/messages/login_hello.js +34 -0
- package/dist/paraglide/messages/login_please_login.d.ts +16 -0
- package/dist/paraglide/messages/login_please_login.js +34 -0
- package/dist/shop/server/orders.d.ts +1 -0
- package/dist/shop/server/orders.js +14 -0
- package/dist/shop/server/shop-data.d.ts +2 -0
- package/dist/shop/server/shop-data.js +20 -5
- package/dist/sveltekit/server/handle.js +17 -0
- package/dist/types/cms.schema.js +4 -2
- package/dist/types/fields.d.ts +35 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/layout.d.ts +35 -2
- package/dist/updates/0.26.0/index.d.ts +2 -0
- package/dist/updates/0.26.0/index.js +51 -0
- package/dist/updates/index.js +3 -1
- package/package.json +29 -7
- package/dist/admin/client/collection/empty-state.svelte +0 -28
- package/dist/admin/client/collection/empty-state.svelte.d.ts +0 -9
- package/dist/admin/client/form/submission-status-badge.svelte +0 -41
- package/dist/admin/client/form/submission-status-badge.svelte.d.ts +0 -7
- package/dist/admin/components/media/file-preview.svelte +0 -51
- package/dist/admin/components/media/file-preview.svelte.d.ts +0 -6
- package/dist/admin/utils/formatDate.d.ts +0 -5
- package/dist/paraglide/messages/en.d.ts +0 -5
- package/dist/paraglide/messages/en.js +0 -14
- package/dist/paraglide/messages/pl.d.ts +0 -5
- package/dist/paraglide/messages/pl.js +0 -14
|
@@ -3,34 +3,41 @@
|
|
|
3
3
|
import type { FormConfig, FormSubmission } from '../../../types/forms.js';
|
|
4
4
|
import type { ColumnDef, RowSelectionState, SortingState, Table } from '@tanstack/table-core';
|
|
5
5
|
import SubmissionLink from './submission-link.svelte';
|
|
6
|
-
import SubmissionStatusBadge from './submission-status-badge.svelte';
|
|
7
6
|
import DataTable from '../collection/data-table.svelte';
|
|
8
7
|
import TablePagination from '../collection/table-pagination.svelte';
|
|
8
|
+
import TableToolbar from '../collection/table-toolbar.svelte';
|
|
9
|
+
import StatusBadge from '../collection/status-badge.svelte';
|
|
10
|
+
import StateDisplay from '../collection/state-display.svelte';
|
|
11
|
+
import BulkActionsBar from '../collection/bulk-actions-bar.svelte';
|
|
12
|
+
import PageHeader from '../../components/layout/page-header.svelte';
|
|
9
13
|
import { getLocalizedLabel } from '../../utils/collectionLabel.js';
|
|
10
14
|
import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
|
|
11
15
|
import type { InterfaceLanguage } from '../../../types/languages.js';
|
|
12
|
-
import {
|
|
16
|
+
import { formatDateTime } from '../../utils/formatters.js';
|
|
13
17
|
import Checkbox from '../../../components/ui/checkbox/checkbox.svelte';
|
|
14
18
|
import { getRemotes } from '../../context/remotes.js';
|
|
15
19
|
import { invalidateAll } from '$app/navigation';
|
|
16
|
-
import Search from '@tabler/icons-svelte/icons/search';
|
|
17
|
-
import FilterIcon from '@tabler/icons-svelte/icons/filter';
|
|
18
20
|
import Download from '@tabler/icons-svelte/icons/download';
|
|
19
21
|
import ChevronDown from '@tabler/icons-svelte/icons/chevron-down';
|
|
20
22
|
import FileSpreadsheet from '@tabler/icons-svelte/icons/file-spreadsheet';
|
|
21
23
|
import FileText from '@tabler/icons-svelte/icons/file-text';
|
|
22
|
-
import Trash from '@tabler/icons-svelte/icons/trash';
|
|
23
24
|
import Eye from '@tabler/icons-svelte/icons/eye';
|
|
24
25
|
import EyeOff from '@tabler/icons-svelte/icons/eye-off';
|
|
25
|
-
import X from '@tabler/icons-svelte/icons/x';
|
|
26
|
-
import ClipboardList from '@tabler/icons-svelte/icons/clipboard-list';
|
|
27
|
-
import Input from '../../../components/ui/input/input.svelte';
|
|
28
26
|
import Button from '../../../components/ui/button/button.svelte';
|
|
29
27
|
import * as Popover from '../../../components/ui/popover/index.js';
|
|
28
|
+
import ConfirmationDialog from '../../components/dialogs/confirmation-dialog.svelte';
|
|
30
29
|
|
|
31
30
|
const interfaceLanguage = useInterfaceLanguage();
|
|
32
31
|
const remotes = getRemotes();
|
|
33
32
|
|
|
33
|
+
function pluralPL(n: number, singular: string, few: string, many: string): string {
|
|
34
|
+
const mod10 = n % 10;
|
|
35
|
+
const mod100 = n % 100;
|
|
36
|
+
if (n === 1) return singular;
|
|
37
|
+
if (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20)) return few;
|
|
38
|
+
return many;
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
type ReadFilter = 'all' | 'unread' | 'read';
|
|
35
42
|
|
|
36
43
|
const lang: Record<
|
|
@@ -38,16 +45,13 @@
|
|
|
38
45
|
{
|
|
39
46
|
createdAt: string;
|
|
40
47
|
status: string;
|
|
41
|
-
new: string;
|
|
42
48
|
read: string;
|
|
43
|
-
submissions: string;
|
|
44
49
|
unread: string;
|
|
45
|
-
unreadCount: string;
|
|
46
50
|
searchPlaceholder: string;
|
|
47
|
-
all: string;
|
|
48
51
|
filterAll: string;
|
|
49
52
|
filterUnread: string;
|
|
50
53
|
filterRead: string;
|
|
54
|
+
filterLabel: string;
|
|
51
55
|
export: string;
|
|
52
56
|
exportCsv: string;
|
|
53
57
|
exportJson: string;
|
|
@@ -55,28 +59,27 @@
|
|
|
55
59
|
noSubmissionsDesc: string;
|
|
56
60
|
noResults: string;
|
|
57
61
|
noResultsDesc: string;
|
|
58
|
-
|
|
62
|
+
unreadDescription: (n: number) => string;
|
|
59
63
|
bulkMarkRead: string;
|
|
60
64
|
bulkMarkUnread: string;
|
|
61
65
|
bulkExport: string;
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
confirmBulkDeleteTitle: (n: number) => string;
|
|
67
|
+
confirmBulkDeleteDescription: string;
|
|
64
68
|
itemLabel: string;
|
|
69
|
+
loadingMessage: string;
|
|
70
|
+
errorMessage: string;
|
|
65
71
|
}
|
|
66
72
|
> = {
|
|
67
73
|
pl: {
|
|
68
74
|
createdAt: 'Wysłano',
|
|
69
75
|
status: 'Status',
|
|
70
|
-
new: 'Nowe',
|
|
71
76
|
read: 'Przeczytane',
|
|
72
|
-
|
|
73
|
-
unread: 'nieprzeczytanych',
|
|
74
|
-
unreadCount: 'nieprzeczytanych',
|
|
77
|
+
unread: 'Nieprzeczytane',
|
|
75
78
|
searchPlaceholder: 'Szukaj zgłoszeń…',
|
|
76
|
-
all: 'Wszystkie',
|
|
77
79
|
filterAll: 'Wszystkie',
|
|
78
80
|
filterUnread: 'Nieprzeczytane',
|
|
79
81
|
filterRead: 'Przeczytane',
|
|
82
|
+
filterLabel: 'Status',
|
|
80
83
|
export: 'Eksportuj',
|
|
81
84
|
exportCsv: 'Eksportuj CSV',
|
|
82
85
|
exportJson: 'Eksportuj JSON',
|
|
@@ -84,27 +87,26 @@
|
|
|
84
87
|
noSubmissionsDesc: 'Nie otrzymano jeszcze żadnych zgłoszeń z tego formularza.',
|
|
85
88
|
noResults: 'Brak wyników',
|
|
86
89
|
noResultsDesc: 'Spróbuj zmienić kryteria wyszukiwania.',
|
|
87
|
-
|
|
90
|
+
unreadDescription: (n) => `${n} nieprzeczytanych`,
|
|
88
91
|
bulkMarkRead: 'Oznacz przeczytane',
|
|
89
92
|
bulkMarkUnread: 'Oznacz nieprzeczytane',
|
|
90
93
|
bulkExport: 'Eksportuj',
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
itemLabel: 'zgłoszeń'
|
|
94
|
+
confirmBulkDeleteTitle: (n: number) => `Usunąć ${n} ${pluralPL(n, 'zgłoszenie', 'zgłoszenia', 'zgłoszeń')}?`,
|
|
95
|
+
confirmBulkDeleteDescription: 'Tej akcji nie cofniesz — zgłoszenia znikną z bazy.',
|
|
96
|
+
itemLabel: 'zgłoszeń',
|
|
97
|
+
loadingMessage: 'Ładowanie zgłoszeń…',
|
|
98
|
+
errorMessage: 'Nie udało się wczytać zgłoszeń.'
|
|
94
99
|
},
|
|
95
100
|
en: {
|
|
96
101
|
createdAt: 'Sent',
|
|
97
102
|
status: 'Status',
|
|
98
|
-
new: 'New',
|
|
99
103
|
read: 'Read',
|
|
100
|
-
|
|
101
|
-
unread: 'unread',
|
|
102
|
-
unreadCount: 'unread',
|
|
104
|
+
unread: 'Unread',
|
|
103
105
|
searchPlaceholder: 'Search submissions…',
|
|
104
|
-
all: 'All',
|
|
105
106
|
filterAll: 'All',
|
|
106
107
|
filterUnread: 'Unread',
|
|
107
108
|
filterRead: 'Read',
|
|
109
|
+
filterLabel: 'Status',
|
|
108
110
|
export: 'Export',
|
|
109
111
|
exportCsv: 'Export CSV',
|
|
110
112
|
exportJson: 'Export JSON',
|
|
@@ -112,13 +114,16 @@
|
|
|
112
114
|
noSubmissionsDesc: 'No submissions have been received from this form yet.',
|
|
113
115
|
noResults: 'No results',
|
|
114
116
|
noResultsDesc: 'Try adjusting your search criteria.',
|
|
115
|
-
|
|
117
|
+
unreadDescription: (n) => `${n} unread`,
|
|
116
118
|
bulkMarkRead: 'Mark read',
|
|
117
119
|
bulkMarkUnread: 'Mark unread',
|
|
118
120
|
bulkExport: 'Export',
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
confirmBulkDeleteTitle: (n: number) =>
|
|
122
|
+
`Delete ${n} ${n === 1 ? 'submission' : 'submissions'}?`,
|
|
123
|
+
confirmBulkDeleteDescription: 'This cannot be undone — submissions will be removed from the database.',
|
|
124
|
+
itemLabel: 'submissions',
|
|
125
|
+
loadingMessage: 'Loading submissions…',
|
|
126
|
+
errorMessage: 'Failed to load submissions.'
|
|
122
127
|
}
|
|
123
128
|
};
|
|
124
129
|
|
|
@@ -130,9 +135,16 @@
|
|
|
130
135
|
type Props = {
|
|
131
136
|
submissions: FormSubmission[];
|
|
132
137
|
formConfig: FormConfig;
|
|
138
|
+
data?: FormSubmission[];
|
|
139
|
+
state?: 'loading' | 'error' | 'ok';
|
|
133
140
|
};
|
|
134
141
|
|
|
135
|
-
let { submissions, formConfig }: Props = $props();
|
|
142
|
+
let { submissions, formConfig, data: injectedData, state: injectedState }: Props = $props();
|
|
143
|
+
|
|
144
|
+
const effectiveSubmissions = $derived(injectedData ?? submissions);
|
|
145
|
+
const tableViewState = $derived<'idle' | 'loading' | 'error'>(
|
|
146
|
+
injectedState === 'loading' ? 'loading' : injectedState === 'error' ? 'error' : 'idle'
|
|
147
|
+
);
|
|
136
148
|
|
|
137
149
|
let searchQuery = $state('');
|
|
138
150
|
let readFilter = $state<ReadFilter>('all');
|
|
@@ -141,7 +153,6 @@
|
|
|
141
153
|
let pageSize = $state(20);
|
|
142
154
|
let tableInstance = $state<Table<SubmissionRow> | null>(null);
|
|
143
155
|
let exportDropdownOpen = $state(false);
|
|
144
|
-
let filterPopoverOpen = $state(false);
|
|
145
156
|
|
|
146
157
|
const t = $derived(lang[interfaceLanguage.current]);
|
|
147
158
|
const formLabel = $derived(
|
|
@@ -149,8 +160,8 @@
|
|
|
149
160
|
);
|
|
150
161
|
|
|
151
162
|
const stats = $derived({
|
|
152
|
-
total:
|
|
153
|
-
unreadCount:
|
|
163
|
+
total: effectiveSubmissions.length,
|
|
164
|
+
unreadCount: effectiveSubmissions.filter((s) => !s.read).length
|
|
154
165
|
});
|
|
155
166
|
|
|
156
167
|
const selectedCount = $derived(
|
|
@@ -167,7 +178,7 @@
|
|
|
167
178
|
);
|
|
168
179
|
|
|
169
180
|
const filteredData = $derived.by(() => {
|
|
170
|
-
let result: SubmissionRow[] =
|
|
181
|
+
let result: SubmissionRow[] = effectiveSubmissions.map((submission) => ({
|
|
171
182
|
...submission,
|
|
172
183
|
...submission.data,
|
|
173
184
|
url: `/admin/form-submissions/${submission.id}`
|
|
@@ -194,14 +205,29 @@
|
|
|
194
205
|
const totalItems = $derived(filteredData.length);
|
|
195
206
|
const pageCount = $derived(Math.ceil(totalItems / pageSize));
|
|
196
207
|
|
|
197
|
-
const
|
|
198
|
-
|
|
208
|
+
const dataFilters = $derived([
|
|
209
|
+
{
|
|
210
|
+
slug: 'read',
|
|
211
|
+
label: t.filterLabel,
|
|
212
|
+
options: [
|
|
213
|
+
{ value: 'all', label: t.filterAll },
|
|
214
|
+
{ value: 'unread', label: t.filterUnread },
|
|
215
|
+
{ value: 'read', label: t.filterRead }
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
]);
|
|
219
|
+
|
|
220
|
+
const activeDataFilters = $derived({
|
|
221
|
+
read: readFilter === 'all' ? null : readFilter
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const headerDescription = $derived(
|
|
225
|
+
stats.unreadCount > 0 ? t.unreadDescription(stats.unreadCount) : undefined
|
|
199
226
|
);
|
|
200
227
|
|
|
201
228
|
const columns = $derived.by(() => {
|
|
202
229
|
const cols: ColumnDef<SubmissionRow>[] = [];
|
|
203
230
|
|
|
204
|
-
// Checkbox column
|
|
205
231
|
cols.push({
|
|
206
232
|
id: 'select',
|
|
207
233
|
header: ({ table }) =>
|
|
@@ -220,22 +246,20 @@
|
|
|
220
246
|
enableHiding: false
|
|
221
247
|
});
|
|
222
248
|
|
|
223
|
-
// Read dot column
|
|
224
249
|
cols.push({
|
|
225
|
-
id: '
|
|
226
|
-
header:
|
|
227
|
-
cell: (info) =>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
250
|
+
id: 'status',
|
|
251
|
+
header: t.status,
|
|
252
|
+
cell: (info) =>
|
|
253
|
+
renderComponent(StatusBadge, {
|
|
254
|
+
variant: 'boolean',
|
|
255
|
+
active: info.row.original.read,
|
|
256
|
+
activeLabel: t.read,
|
|
257
|
+
inactiveLabel: t.unread
|
|
258
|
+
}),
|
|
233
259
|
enableSorting: false,
|
|
234
|
-
|
|
235
|
-
size: 32
|
|
260
|
+
size: 130
|
|
236
261
|
});
|
|
237
262
|
|
|
238
|
-
// Dynamic field columns
|
|
239
263
|
const firstShowField = formConfig.fields.find((f) => f.showInDataTable);
|
|
240
264
|
formConfig.fields.forEach((field) => {
|
|
241
265
|
if (!field.showInDataTable) return;
|
|
@@ -271,7 +295,6 @@
|
|
|
271
295
|
cols.push(col);
|
|
272
296
|
});
|
|
273
297
|
|
|
274
|
-
// Message preview column (find textarea field not in showInDataTable)
|
|
275
298
|
const messageField = formConfig.fields.find(
|
|
276
299
|
(f) => f.type === 'textarea' && !f.showInDataTable
|
|
277
300
|
);
|
|
@@ -292,13 +315,12 @@
|
|
|
292
315
|
});
|
|
293
316
|
}
|
|
294
317
|
|
|
295
|
-
// Date column
|
|
296
318
|
cols.push({
|
|
297
319
|
accessorKey: 'createdAt',
|
|
298
320
|
header: t.createdAt,
|
|
299
321
|
cell: (info) => {
|
|
300
322
|
const date = new Date(info.row.original.createdAt);
|
|
301
|
-
return
|
|
323
|
+
return formatDateTime(date, interfaceLanguage.current);
|
|
302
324
|
}
|
|
303
325
|
});
|
|
304
326
|
|
|
@@ -318,7 +340,7 @@
|
|
|
318
340
|
}
|
|
319
341
|
|
|
320
342
|
async function handleExportJson() {
|
|
321
|
-
const blob = new Blob([JSON.stringify(
|
|
343
|
+
const blob = new Blob([JSON.stringify(effectiveSubmissions, null, 2)], {
|
|
322
344
|
type: 'application/json'
|
|
323
345
|
});
|
|
324
346
|
const url = URL.createObjectURL(blob);
|
|
@@ -346,94 +368,29 @@
|
|
|
346
368
|
invalidateAll();
|
|
347
369
|
}
|
|
348
370
|
|
|
349
|
-
|
|
371
|
+
let confirmBulkDeleteOpen = $state(false);
|
|
372
|
+
let bulkDeleting = $state(false);
|
|
373
|
+
|
|
374
|
+
function handleBulkDelete() {
|
|
350
375
|
if (selectedIds.length === 0) return;
|
|
351
|
-
|
|
352
|
-
await remotes.deleteFormSubmissions(selectedIds);
|
|
353
|
-
rowSelection = {};
|
|
354
|
-
invalidateAll();
|
|
376
|
+
confirmBulkDeleteOpen = true;
|
|
355
377
|
}
|
|
356
378
|
|
|
379
|
+
async function performBulkDelete() {
|
|
380
|
+
bulkDeleting = true;
|
|
381
|
+
try {
|
|
382
|
+
await remotes.deleteFormSubmissions(selectedIds);
|
|
383
|
+
rowSelection = {};
|
|
384
|
+
invalidateAll();
|
|
385
|
+
} finally {
|
|
386
|
+
bulkDeleting = false;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
357
389
|
</script>
|
|
358
390
|
|
|
359
391
|
<div class="space-y-5">
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
<div class="mb-1 flex flex-wrap items-center gap-3">
|
|
363
|
-
<h1 class="text-2xl font-bold">{formLabel}</h1>
|
|
364
|
-
<span
|
|
365
|
-
class="bg-lavender-lighter text-primary inline-flex h-6 items-center rounded-full px-2.5 text-xs font-bold"
|
|
366
|
-
aria-label="{stats.total} {t.submissions}"
|
|
367
|
-
>
|
|
368
|
-
{stats.total} {t.submissions}
|
|
369
|
-
</span>
|
|
370
|
-
{#if stats.unreadCount > 0}
|
|
371
|
-
<span
|
|
372
|
-
class="inline-flex h-6 items-center rounded-full bg-amber-50 px-2.5 text-xs font-semibold text-amber-600"
|
|
373
|
-
aria-label="{stats.unreadCount} {t.unreadCount}"
|
|
374
|
-
>
|
|
375
|
-
{stats.unreadCount} {t.unreadCount}
|
|
376
|
-
</span>
|
|
377
|
-
{/if}
|
|
378
|
-
</div>
|
|
379
|
-
|
|
380
|
-
<!-- Toolbar -->
|
|
381
|
-
<div class="mt-4 flex flex-wrap items-center gap-2.5">
|
|
382
|
-
<div class="relative min-w-[240px] flex-1">
|
|
383
|
-
<Search
|
|
384
|
-
class="text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2"
|
|
385
|
-
/>
|
|
386
|
-
<Input
|
|
387
|
-
type="search"
|
|
388
|
-
placeholder={t.searchPlaceholder}
|
|
389
|
-
class="border-border bg-white pl-9"
|
|
390
|
-
value={searchQuery}
|
|
391
|
-
oninput={(e) => (searchQuery = e.currentTarget.value)}
|
|
392
|
-
aria-label={t.searchPlaceholder}
|
|
393
|
-
/>
|
|
394
|
-
</div>
|
|
395
|
-
|
|
396
|
-
<Popover.Root bind:open={filterPopoverOpen}>
|
|
397
|
-
<Popover.Trigger>
|
|
398
|
-
{#snippet child({ props })}
|
|
399
|
-
<Button
|
|
400
|
-
{...props}
|
|
401
|
-
variant="outline"
|
|
402
|
-
size="sm"
|
|
403
|
-
class="gap-1.5 {readFilter !== 'all'
|
|
404
|
-
? 'border-primary/30 bg-lavender-lighter text-primary'
|
|
405
|
-
: ''}"
|
|
406
|
-
>
|
|
407
|
-
<FilterIcon class="size-3.5" />
|
|
408
|
-
{activeFilterLabel}
|
|
409
|
-
</Button>
|
|
410
|
-
{/snippet}
|
|
411
|
-
</Popover.Trigger>
|
|
412
|
-
<Popover.Content class="w-40 p-1" align="start">
|
|
413
|
-
{#each ['all', 'unread', 'read'] as filter}
|
|
414
|
-
<button
|
|
415
|
-
class="hover:bg-accent flex w-full items-center rounded-md px-2.5 py-1.5 text-sm transition-colors {readFilter ===
|
|
416
|
-
filter
|
|
417
|
-
? 'bg-accent text-accent-foreground font-medium'
|
|
418
|
-
: 'text-foreground'}"
|
|
419
|
-
onclick={() => {
|
|
420
|
-
readFilter = filter as ReadFilter;
|
|
421
|
-
filterPopoverOpen = false;
|
|
422
|
-
}}
|
|
423
|
-
>
|
|
424
|
-
{filter === 'all'
|
|
425
|
-
? t.filterAll
|
|
426
|
-
: filter === 'unread'
|
|
427
|
-
? t.filterUnread
|
|
428
|
-
: t.filterRead}
|
|
429
|
-
</button>
|
|
430
|
-
{/each}
|
|
431
|
-
</Popover.Content>
|
|
432
|
-
</Popover.Root>
|
|
433
|
-
|
|
434
|
-
<div class="flex-1"></div>
|
|
435
|
-
|
|
436
|
-
<!-- Export dropdown -->
|
|
392
|
+
<PageHeader title={formLabel} count={stats.total} description={headerDescription}>
|
|
393
|
+
{#snippet secondaryActions()}
|
|
437
394
|
<Popover.Root bind:open={exportDropdownOpen}>
|
|
438
395
|
<Popover.Trigger>
|
|
439
396
|
{#snippet child({ props })}
|
|
@@ -461,24 +418,30 @@
|
|
|
461
418
|
</button>
|
|
462
419
|
</Popover.Content>
|
|
463
420
|
</Popover.Root>
|
|
464
|
-
|
|
465
|
-
</
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
<
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
>
|
|
474
|
-
<ClipboardList class="text-muted-foreground size-8" />
|
|
475
|
-
</div>
|
|
476
|
-
<h2 class="mb-1.5 text-lg font-bold">{t.noSubmissions}</h2>
|
|
477
|
-
<p class="text-muted-foreground max-w-[360px] text-sm leading-relaxed">
|
|
478
|
-
{t.noSubmissionsDesc}
|
|
479
|
-
</p>
|
|
480
|
-
</div>
|
|
421
|
+
{/snippet}
|
|
422
|
+
</PageHeader>
|
|
423
|
+
|
|
424
|
+
{#if tableViewState === 'error'}
|
|
425
|
+
<StateDisplay kind="error" title={t.errorMessage} />
|
|
426
|
+
{:else if tableViewState === 'loading'}
|
|
427
|
+
<StateDisplay kind="loading" title={t.loadingMessage} />
|
|
428
|
+
{:else if effectiveSubmissions.length === 0}
|
|
429
|
+
<StateDisplay kind="empty" title={t.noSubmissions} description={t.noSubmissionsDesc} />
|
|
481
430
|
{:else}
|
|
431
|
+
<TableToolbar
|
|
432
|
+
{searchQuery}
|
|
433
|
+
searchPlaceholder={t.searchPlaceholder}
|
|
434
|
+
searchLabel={t.searchPlaceholder}
|
|
435
|
+
onSearchChange={(q) => (searchQuery = q)}
|
|
436
|
+
hideStatusFilter
|
|
437
|
+
hideViewToggle
|
|
438
|
+
{dataFilters}
|
|
439
|
+
{activeDataFilters}
|
|
440
|
+
onDataFilterChange={(_slug, value) => {
|
|
441
|
+
readFilter = (value as ReadFilter | null) ?? 'all';
|
|
442
|
+
}}
|
|
443
|
+
/>
|
|
444
|
+
|
|
482
445
|
<div class="overflow-hidden rounded-xl border bg-card shadow-sm">
|
|
483
446
|
<DataTable
|
|
484
447
|
data={filteredData}
|
|
@@ -493,9 +456,8 @@
|
|
|
493
456
|
onRowSelectionChange={(s) => (rowSelection = s)}
|
|
494
457
|
pagination={{ pageIndex: 0, pageSize }}
|
|
495
458
|
tableRef={(t) => (tableInstance = t)}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
: t.noSubmissions}
|
|
459
|
+
emptyTitle={searchQuery || readFilter !== 'all' ? t.noResults : t.noSubmissions}
|
|
460
|
+
emptyDescription={searchQuery || readFilter !== 'all' ? t.noResultsDesc : t.noSubmissionsDesc}
|
|
499
461
|
/>
|
|
500
462
|
|
|
501
463
|
<TablePagination
|
|
@@ -514,59 +476,46 @@
|
|
|
514
476
|
{/if}
|
|
515
477
|
</div>
|
|
516
478
|
|
|
517
|
-
|
|
518
|
-
{
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
>
|
|
524
|
-
<span class="text-sm font-bold whitespace-nowrap">{t.bulkSelected(selectedCount)}</span>
|
|
525
|
-
<div class="h-5 w-px bg-white/20"></div>
|
|
479
|
+
<BulkActionsBar
|
|
480
|
+
{selectedCount}
|
|
481
|
+
onDelete={handleBulkDelete}
|
|
482
|
+
onClear={() => (rowSelection = {})}
|
|
483
|
+
>
|
|
484
|
+
{#snippet actions()}
|
|
526
485
|
<Button
|
|
527
486
|
variant="ghost"
|
|
528
487
|
size="sm"
|
|
529
|
-
class="
|
|
488
|
+
class="border border-white/20 text-white hover:bg-white/10 hover:text-white"
|
|
530
489
|
onclick={handleBulkMarkRead}
|
|
531
490
|
>
|
|
532
|
-
<Eye class="size-3.5" />
|
|
491
|
+
<Eye class="mr-1.5 size-3.5" />
|
|
533
492
|
{t.bulkMarkRead}
|
|
534
493
|
</Button>
|
|
535
494
|
<Button
|
|
536
495
|
variant="ghost"
|
|
537
496
|
size="sm"
|
|
538
|
-
class="
|
|
497
|
+
class="border border-white/20 text-white hover:bg-white/10 hover:text-white"
|
|
539
498
|
onclick={handleBulkMarkUnread}
|
|
540
499
|
>
|
|
541
|
-
<EyeOff class="size-3.5" />
|
|
500
|
+
<EyeOff class="mr-1.5 size-3.5" />
|
|
542
501
|
{t.bulkMarkUnread}
|
|
543
502
|
</Button>
|
|
544
503
|
<Button
|
|
545
504
|
variant="ghost"
|
|
546
505
|
size="sm"
|
|
547
|
-
class="
|
|
506
|
+
class="border border-white/20 text-white hover:bg-white/10 hover:text-white"
|
|
548
507
|
onclick={handleExportCsv}
|
|
549
508
|
>
|
|
550
|
-
<Download class="size-3.5" />
|
|
509
|
+
<Download class="mr-1.5 size-3.5" />
|
|
551
510
|
{t.bulkExport}
|
|
552
511
|
</Button>
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
variant="ghost"
|
|
564
|
-
size="icon"
|
|
565
|
-
class="ml-1 size-7 text-white/60 hover:bg-white/10 hover:text-white"
|
|
566
|
-
onclick={() => (rowSelection = {})}
|
|
567
|
-
>
|
|
568
|
-
<X class="size-3.5" />
|
|
569
|
-
</Button>
|
|
570
|
-
</div>
|
|
571
|
-
{/if}
|
|
572
|
-
|
|
512
|
+
{/snippet}
|
|
513
|
+
</BulkActionsBar>
|
|
514
|
+
|
|
515
|
+
<ConfirmationDialog
|
|
516
|
+
bind:open={confirmBulkDeleteOpen}
|
|
517
|
+
title={t.confirmBulkDeleteTitle(selectedIds.length)}
|
|
518
|
+
description={t.confirmBulkDeleteDescription}
|
|
519
|
+
loading={bulkDeleting}
|
|
520
|
+
onConfirm={performBulkDelete}
|
|
521
|
+
/>
|
|
@@ -2,6 +2,8 @@ import type { FormConfig, FormSubmission } from '../../../types/forms.js';
|
|
|
2
2
|
type Props = {
|
|
3
3
|
submissions: FormSubmission[];
|
|
4
4
|
formConfig: FormConfig;
|
|
5
|
+
data?: FormSubmission[];
|
|
6
|
+
state?: 'loading' | 'error' | 'ok';
|
|
5
7
|
};
|
|
6
8
|
declare const FormSubmissions: import("svelte").Component<Props, {}, "">;
|
|
7
9
|
type FormSubmissions = ReturnType<typeof FormSubmissions>;
|
|
@@ -12,6 +12,8 @@ export declare const loginLang: Record<string, {
|
|
|
12
12
|
form_label: string;
|
|
13
13
|
login_error: string;
|
|
14
14
|
login_success: string;
|
|
15
|
+
email_invalid: string;
|
|
16
|
+
password_too_short: string;
|
|
15
17
|
};
|
|
16
18
|
forgot: {
|
|
17
19
|
heading: string;
|
|
@@ -37,5 +39,6 @@ export declare const loginLang: Record<string, {
|
|
|
37
39
|
passwordHint: string;
|
|
38
40
|
passwordMinLength: string;
|
|
39
41
|
passwordRequirements: string;
|
|
42
|
+
generatePassword: string;
|
|
40
43
|
};
|
|
41
44
|
}>;
|
|
@@ -12,7 +12,9 @@ export const loginLang = {
|
|
|
12
12
|
skip_to_content: 'Przejdź do treści',
|
|
13
13
|
form_label: 'Logowanie',
|
|
14
14
|
login_error: 'Nieprawidłowy e-mail lub hasło. Spróbuj ponownie.',
|
|
15
|
-
login_success: 'Zalogowano pomyślnie'
|
|
15
|
+
login_success: 'Zalogowano pomyślnie',
|
|
16
|
+
email_invalid: 'Podaj poprawny adres e-mail',
|
|
17
|
+
password_too_short: 'Hasło jest za krótkie'
|
|
16
18
|
},
|
|
17
19
|
forgot: {
|
|
18
20
|
heading: 'Przypomnij hasło',
|
|
@@ -37,7 +39,8 @@ export const loginLang = {
|
|
|
37
39
|
form_label: 'Zmiana hasła',
|
|
38
40
|
passwordHint: 'Min. 8 znaków, wielka litera, cyfra i znak specjalny',
|
|
39
41
|
passwordMinLength: 'Hasło musi mieć min. 8 znaków',
|
|
40
|
-
passwordRequirements: 'Hasło musi zawierać wielką literę, cyfrę i znak specjalny'
|
|
42
|
+
passwordRequirements: 'Hasło musi zawierać wielką literę, cyfrę i znak specjalny',
|
|
43
|
+
generatePassword: 'Wygeneruj hasło'
|
|
41
44
|
}
|
|
42
45
|
},
|
|
43
46
|
en: {
|
|
@@ -53,7 +56,9 @@ export const loginLang = {
|
|
|
53
56
|
skip_to_content: 'Skip to content',
|
|
54
57
|
form_label: 'Login',
|
|
55
58
|
login_error: 'Invalid email or password. Please try again.',
|
|
56
|
-
login_success: 'Logged in successfully'
|
|
59
|
+
login_success: 'Logged in successfully',
|
|
60
|
+
email_invalid: 'Enter a valid email address',
|
|
61
|
+
password_too_short: 'Password is too short'
|
|
57
62
|
},
|
|
58
63
|
forgot: {
|
|
59
64
|
heading: 'Forgot password',
|
|
@@ -78,7 +83,8 @@ export const loginLang = {
|
|
|
78
83
|
form_label: 'Reset password',
|
|
79
84
|
passwordHint: 'Min. 8 characters, uppercase, number and special character',
|
|
80
85
|
passwordMinLength: 'Password must be at least 8 characters',
|
|
81
|
-
passwordRequirements: 'Password must contain an uppercase letter, a number and a special character'
|
|
86
|
+
passwordRequirements: 'Password must contain an uppercase letter, a number and a special character',
|
|
87
|
+
generatePassword: 'Generate password'
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
90
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { defaults, superForm } from 'sveltekit-superforms';
|
|
6
6
|
import { zod4, zod4Client } from 'sveltekit-superforms/adapters';
|
|
7
|
-
import {
|
|
7
|
+
import { createLoginSchema, createForgotPasswordSchema } from './schema.js';
|
|
8
8
|
import { toast } from 'svelte-sonner';
|
|
9
9
|
import { authClient } from '../../auth-client.js';
|
|
10
10
|
import { loginLang } from './lang.js';
|
|
@@ -17,6 +17,13 @@
|
|
|
17
17
|
const lang = () => loginLang[interfaceLanguage.current].login;
|
|
18
18
|
const forgotLang = () => loginLang[interfaceLanguage.current].forgot;
|
|
19
19
|
|
|
20
|
+
// superForm is initialized once — capture the current language for validation messages
|
|
21
|
+
const loginSchema = createLoginSchema({
|
|
22
|
+
emailInvalid: lang().email_invalid,
|
|
23
|
+
passwordTooShort: lang().password_too_short
|
|
24
|
+
});
|
|
25
|
+
const forgotPasswordSchema = createForgotPasswordSchema({ emailInvalid: lang().email_invalid });
|
|
26
|
+
|
|
20
27
|
let mode: 'login' | 'forgot' | 'forgot-sent' = $state('login');
|
|
21
28
|
let forgotLoading = $state(false);
|
|
22
29
|
let forgotError = $state('');
|