@eifi1/ui-kit 0.54.0 → 0.56.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/README.md +90 -76
- package/dist/admin/plan-change.js +2 -2
- package/dist/admin/plan-change.js.map +1 -1
- package/dist/admin/user-roster.d.ts +6 -0
- package/dist/admin/user-roster.js +4 -0
- package/dist/admin/user-roster.js.map +1 -1
- package/dist/billing/billing-labels.d.ts +26 -0
- package/dist/billing/billing-labels.js +9 -0
- package/dist/billing/billing-labels.js.map +1 -1
- package/dist/billing/subscription-standing.d.ts +61 -0
- package/dist/billing/subscription-standing.js +51 -0
- package/dist/billing/subscription-standing.js.map +1 -0
- package/dist/billing/usage-meter.d.ts +52 -0
- package/dist/billing/usage-meter.js +52 -0
- package/dist/billing/usage-meter.js.map +1 -0
- package/dist/chart.d.ts +1 -0
- package/dist/chart.js +4 -0
- package/dist/chart.js.map +1 -1
- package/dist/components/alert-banner.js +2 -3
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.js +3 -15
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.js +2 -2
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/bulk-action-bar.js +2 -1
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button.d.ts +35 -1
- package/dist/components/button.js +6 -9
- package/dist/components/button.js.map +1 -1
- package/dist/components/calendar-heatmap.js +2 -2
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/camera-button.d.ts +89 -0
- package/dist/components/camera-button.js +122 -0
- package/dist/components/camera-button.js.map +1 -0
- package/dist/components/camera-capture.d.ts +66 -0
- package/dist/components/camera-capture.js +190 -0
- package/dist/components/camera-capture.js.map +1 -0
- package/dist/components/camera-labels.d.ts +20 -0
- package/dist/components/camera-labels.js +15 -0
- package/dist/components/camera-labels.js.map +1 -0
- package/dist/components/chart-edge.d.ts +9 -0
- package/dist/components/chart-edge.js +14 -3
- package/dist/components/chart-edge.js.map +1 -1
- package/dist/components/chart-zoom-core.js +34 -29
- package/dist/components/chart-zoom-core.js.map +1 -1
- package/dist/components/checkbox-group.js +1 -1
- package/dist/components/checkbox-group.js.map +1 -1
- package/dist/components/combobox-core.js +3 -2
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.js +2 -2
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/consent-again-notice-labels.d.ts +25 -0
- package/dist/components/consent-again-notice-labels.js +15 -0
- package/dist/components/consent-again-notice-labels.js.map +1 -0
- package/dist/components/consent-again-notice.d.ts +85 -0
- package/dist/components/consent-again-notice.js +94 -0
- package/dist/components/consent-again-notice.js.map +1 -0
- package/dist/components/country-select.js +2 -7
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/currency-select.js +2 -2
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.js +2 -2
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-column-settings.js +2 -2
- package/dist/components/data-table-column-settings.js.map +1 -1
- package/dist/components/data-table-fit.js.map +1 -1
- package/dist/components/data-table-virtual.js +13 -3
- package/dist/components/data-table-virtual.js.map +1 -1
- package/dist/components/date-field.js +2 -2
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.js +2 -2
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.js +2 -6
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/dialog-frame.d.ts +3 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/dropdown.js +7 -3
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/entity-combobox.js +2 -2
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/field-parts.d.ts +108 -6
- package/dist/components/field-parts.js +59 -6
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-suggestion-labels.d.ts +2 -0
- package/dist/components/field-suggestion-labels.js +10 -0
- package/dist/components/field-suggestion-labels.js.map +1 -0
- package/dist/components/field.js +1 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-button.d.ts +1 -1
- package/dist/components/file-button.js.map +1 -1
- package/dist/components/floating-panel.d.ts +7 -6
- package/dist/components/floating-panel.js +3 -17
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/form-actions.d.ts +3 -2
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/hover-menu.js +3 -2
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/icon-button.d.ts +23 -5
- package/dist/components/icon-button.js +7 -8
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/inline-confirm.js +2 -1
- package/dist/components/inline-confirm.js.map +1 -1
- package/dist/components/inline-entity-combobox.js +2 -2
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/input.js +2 -2
- package/dist/components/input.js.map +1 -1
- package/dist/components/jump-calendar.js +3 -3
- package/dist/components/jump-calendar.js.map +1 -1
- package/dist/components/legal.d.ts +13 -1
- package/dist/components/legal.js +12 -0
- package/dist/components/legal.js.map +1 -1
- package/dist/components/legended-series-chart.d.ts +83 -0
- package/dist/components/legended-series-chart.js +77 -0
- package/dist/components/legended-series-chart.js.map +1 -0
- package/dist/components/lightbox.js +2 -1
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/mini-calendar.js +13 -5
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +23 -2
- package/dist/components/modal.js +24 -6
- package/dist/components/modal.js.map +1 -1
- package/dist/components/month-picker.d.ts +1 -1
- package/dist/components/month-picker.js +6 -6
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-entity-combobox.js +2 -2
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/multi-select.js +2 -6
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/number-input.js +2 -2
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/page-header-layout.d.ts +18 -0
- package/dist/components/page-header-layout.js +23 -0
- package/dist/components/page-header-layout.js.map +1 -0
- package/dist/components/page-header-skeleton.d.ts +41 -0
- package/dist/components/page-header-skeleton.js +52 -0
- package/dist/components/page-header-skeleton.js.map +1 -0
- package/dist/components/page-header.js +4 -17
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/popover.js +7 -2
- package/dist/components/popover.js.map +1 -1
- package/dist/components/release-notes-labels.d.ts +16 -0
- package/dist/components/release-notes-labels.js +18 -0
- package/dist/components/release-notes-labels.js.map +1 -0
- package/dist/components/release-notes.d.ts +65 -0
- package/dist/components/release-notes.js +65 -0
- package/dist/components/release-notes.js.map +1 -0
- package/dist/components/select.js +2 -2
- package/dist/components/select.js.map +1 -1
- package/dist/components/series-chart-labels.d.ts +9 -0
- package/dist/components/series-chart-labels.js +3 -1
- package/dist/components/series-chart-labels.js.map +1 -1
- package/dist/components/series-chart.d.ts +5 -0
- package/dist/components/series-chart.js +89 -36
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/toggle-group.js +3 -2
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/treemap-layout.js.map +1 -1
- package/dist/components/treemap.d.ts +17 -15
- package/dist/components/treemap.js +167 -85
- package/dist/components/treemap.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/eslint/role-utilities.d.ts +2 -2
- package/dist/eslint/role-utilities.js.map +1 -1
- package/dist/feedback/feedback-inbox-page.d.ts +260 -0
- package/dist/feedback/feedback-inbox-page.js +207 -0
- package/dist/feedback/feedback-inbox-page.js.map +1 -0
- package/dist/feedback/feedback-vocabulary.js +2 -2
- package/dist/feedback/feedback-vocabulary.js.map +1 -1
- package/dist/feedback.d.ts +1 -0
- package/dist/feedback.js +6 -0
- package/dist/feedback.js.map +1 -1
- package/dist/hooks/use-debounce.d.ts +32 -5
- package/dist/hooks/use-debounce.js +6 -5
- package/dist/hooks/use-debounce.js.map +1 -1
- package/dist/hooks/use-file-picker.d.ts +3 -1
- package/dist/hooks/use-file-picker.js.map +1 -1
- package/dist/hooks/use-focus-trap.d.ts +19 -3
- package/dist/hooks/use-focus-trap.js +15 -5
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-has-camera.d.ts +36 -0
- package/dist/hooks/use-has-camera.js +53 -0
- package/dist/hooks/use-has-camera.js.map +1 -0
- package/dist/hooks/use-hotkey.js +1 -10
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/hooks/use-overlay-history.d.ts +6 -1
- package/dist/hooks/use-overlay-history.js +10 -2
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/i18n/defaults.js +11 -1
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +75 -3
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +20 -0
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +92 -4
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +71 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +72 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +74 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +74 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +71 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +22 -1
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +24 -5
- package/dist/index.js +35 -1
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-labels.d.ts +8 -0
- package/dist/landing/landing-labels.js +2 -1
- package/dist/landing/landing-labels.js.map +1 -1
- package/dist/lib/changelog.d.ts +130 -0
- package/dist/lib/changelog.js +137 -0
- package/dist/lib/changelog.js.map +1 -0
- package/dist/lib/clipboard-minus.js +2 -2
- package/dist/lib/clipboard-minus.js.map +1 -1
- package/dist/lib/dates.d.ts +29 -3
- package/dist/lib/dates.js +41 -12
- package/dist/lib/dates.js.map +1 -1
- package/dist/lib/editable-content.d.ts +33 -0
- package/dist/lib/editable-content.js +15 -0
- package/dist/lib/editable-content.js.map +1 -0
- package/dist/lib/focus-left.d.ts +47 -1
- package/dist/lib/focus-left.js +11 -2
- package/dist/lib/focus-left.js.map +1 -1
- package/dist/lib/server-wake.d.ts +49 -9
- package/dist/lib/server-wake.js +25 -14
- package/dist/lib/server-wake.js.map +1 -1
- package/dist/lib/session-refresh.d.ts +53 -0
- package/dist/lib/session-refresh.js +27 -1
- package/dist/lib/session-refresh.js.map +1 -1
- package/dist/rhf/fields.js +3 -3
- package/dist/rhf/fields.js.map +1 -1
- package/dist/shell/app-shell.d.ts +25 -1
- package/dist/shell/app-shell.js +3 -1
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/dev-menu.d.ts +3 -0
- package/dist/shell/dev-menu.js +4 -2
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/held-changes-banner-labels.d.ts +23 -0
- package/dist/shell/held-changes-banner-labels.js +14 -0
- package/dist/shell/held-changes-banner-labels.js.map +1 -0
- package/dist/shell/held-changes-banner.d.ts +75 -0
- package/dist/shell/held-changes-banner.js +106 -0
- package/dist/shell/held-changes-banner.js.map +1 -0
- package/dist/shell/sync-status-indicator.d.ts +27 -12
- package/dist/shell/sync-status-indicator.js +13 -4
- package/dist/shell/sync-status-indicator.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +5 -0
- package/dist/shell/top-bar-parts-labels.js +3 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +2 -0
- package/dist/shell.js +3 -0
- package/dist/shell.js.map +1 -1
- package/dist/sync/engine.d.ts +11 -2
- package/dist/sync/engine.js +13 -5
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync/hooks.d.ts +3 -2
- package/dist/sync/hooks.js +4 -2
- package/dist/sync/hooks.js.map +1 -1
- package/dist/testing/css-variables.generated.d.ts +2 -2
- package/dist/testing/css-variables.generated.js +1 -1
- package/dist/testing/css-variables.generated.js.map +1 -1
- package/dist/theme/chart-palette.d.ts +18 -0
- package/dist/theme/chart-palette.js +17 -1
- package/dist/theme/chart-palette.js.map +1 -1
- package/dist/theme/contrast-tokens.d.ts +3 -3
- package/dist/theme/contrast-tokens.js.map +1 -1
- package/dist/theme/contrast.d.ts +4 -4
- package/dist/theme/contrast.js.map +1 -1
- package/dist/tour/tour-overlay.js +2 -1
- package/dist/tour/tour-overlay.js.map +1 -1
- package/package.json +9 -12
- package/tokens.css +19 -54
- package/src/account/account-parts.ts +0 -47
- package/src/account/account-settings-labels.ts +0 -240
- package/src/account/account-settings.tsx +0 -698
- package/src/account/data-export-setting-labels.ts +0 -20
- package/src/account/data-export-setting.tsx +0 -200
- package/src/account/delete-account-setting-labels.ts +0 -33
- package/src/account/delete-account-setting.tsx +0 -342
- package/src/account/email-change-setting-labels.ts +0 -31
- package/src/account/email-change-setting.tsx +0 -443
- package/src/account/passkeys-setting.tsx +0 -445
- package/src/account/sessions-setting-labels.ts +0 -24
- package/src/account/sessions-setting.tsx +0 -283
- package/src/admin/admin-action-confirm-labels.ts +0 -19
- package/src/admin/admin-action-confirm.tsx +0 -509
- package/src/admin/admin-action-log-labels.ts +0 -83
- package/src/admin/admin-action-log.tsx +0 -464
- package/src/admin/admin-area-labels.ts +0 -114
- package/src/admin/admin-forbidden.tsx +0 -75
- package/src/admin/admin-overview.tsx +0 -258
- package/src/admin/admin-parts.ts +0 -68
- package/src/admin/admin-sections.tsx +0 -208
- package/src/admin/admin-tool-links.tsx +0 -90
- package/src/admin/invitations-panel-labels.ts +0 -31
- package/src/admin/invitations-panel.tsx +0 -516
- package/src/admin/mail-test-card-labels.ts +0 -19
- package/src/admin/mail-test-card.tsx +0 -189
- package/src/admin/plan-change-labels.ts +0 -5
- package/src/admin/plan-change.tsx +0 -474
- package/src/admin/reviewer-scope-editor-labels.ts +0 -16
- package/src/admin/reviewer-scope-editor.tsx +0 -224
- package/src/admin/role-select-labels.ts +0 -16
- package/src/admin/role-select.tsx +0 -282
- package/src/admin/transfer-ownership-dialog-labels.ts +0 -20
- package/src/admin/transfer-ownership-dialog.tsx +0 -162
- package/src/admin/user-roster-labels.ts +0 -17
- package/src/admin/user-roster.tsx +0 -559
- package/src/auth/accept-invitation-labels.ts +0 -21
- package/src/auth/accept-invitation.tsx +0 -210
- package/src/auth/auth-errors-labels.ts +0 -23
- package/src/auth/auth-errors.ts +0 -439
- package/src/auth/complete-name-dialog-labels.ts +0 -16
- package/src/auth/complete-name-dialog.tsx +0 -253
- package/src/auth/email-tag.ts +0 -75
- package/src/auth/forgot-password-form-labels.ts +0 -20
- package/src/auth/forgot-password-form.tsx +0 -221
- package/src/auth/form-rules.ts +0 -40
- package/src/auth/new-password-fields.tsx +0 -85
- package/src/auth/not-found-page-labels.ts +0 -12
- package/src/auth/not-found-page.tsx +0 -95
- package/src/auth/register-form-labels.ts +0 -31
- package/src/auth/register-form.tsx +0 -456
- package/src/auth/reset-password-form-labels.ts +0 -27
- package/src/auth/reset-password-form.tsx +0 -341
- package/src/auth/sign-in-form-labels.ts +0 -44
- package/src/auth/sign-in-form.tsx +0 -858
- package/src/auth/status-parts.tsx +0 -132
- package/src/auth/verify-email-labels.ts +0 -26
- package/src/auth/verify-email.tsx +0 -445
- package/src/billing/billing-banner.tsx +0 -258
- package/src/billing/billing-labels.ts +0 -381
- package/src/billing/billing-lock.ts +0 -108
- package/src/billing/billing-overview.ts +0 -157
- package/src/billing/billing-standing.ts +0 -80
- package/src/billing/cancel-request.ts +0 -97
- package/src/billing/cancel-subscription.tsx +0 -98
- package/src/billing/checkout-processing.ts +0 -394
- package/src/billing/checkout-return.ts +0 -90
- package/src/billing/pay-page.ts +0 -330
- package/src/billing/plan-card.tsx +0 -562
- package/src/billing/plan-change-labels.ts +0 -66
- package/src/billing/plan-limit-notice.tsx +0 -148
- package/src/billing/plan-limit-toast.tsx +0 -90
- package/src/billing/plan-limit.ts +0 -52
- package/src/billing/plan-price.ts +0 -98
- package/src/billing/plan-switch.tsx +0 -216
- package/src/billing/provider-page.ts +0 -84
- package/src/billing/subscription-actions.tsx +0 -247
- package/src/billing/subscription-status-chip.tsx +0 -95
- package/src/chart.ts +0 -103
- package/src/components/account-chips-labels.ts +0 -16
- package/src/components/account-chips.tsx +0 -474
- package/src/components/alert-banner.tsx +0 -670
- package/src/components/amount-input.tsx +0 -816
- package/src/components/appearance-labels.ts +0 -63
- package/src/components/authed-image-labels.ts +0 -11
- package/src/components/authed-image.tsx +0 -209
- package/src/components/autocomplete.tsx +0 -645
- package/src/components/breadcrumbs-labels.ts +0 -10
- package/src/components/breadcrumbs.tsx +0 -205
- package/src/components/bulk-action-bar-labels.ts +0 -11
- package/src/components/bulk-action-bar.tsx +0 -443
- package/src/components/button-group.tsx +0 -223
- package/src/components/button-look.ts +0 -256
- package/src/components/button.tsx +0 -339
- package/src/components/calculator.tsx +0 -341
- package/src/components/calendar-heatmap-labels.ts +0 -15
- package/src/components/calendar-heatmap.tsx +0 -600
- package/src/components/card.tsx +0 -377
- package/src/components/chart-edge.ts +0 -106
- package/src/components/chart-figure.tsx +0 -35
- package/src/components/chart-height.ts +0 -30
- package/src/components/chart-zoom-core.tsx +0 -627
- package/src/components/chart-zoom.tsx +0 -22
- package/src/components/chart.tsx +0 -554
- package/src/components/checkbox-group.tsx +0 -247
- package/src/components/checkbox.tsx +0 -346
- package/src/components/chip-input.tsx +0 -370
- package/src/components/chip-labels.ts +0 -13
- package/src/components/chip.tsx +0 -843
- package/src/components/choice-card.tsx +0 -544
- package/src/components/column-mapper-labels.ts +0 -38
- package/src/components/column-mapper.tsx +0 -655
- package/src/components/combobox-core.tsx +0 -1321
- package/src/components/combobox-suggestions.tsx +0 -131
- package/src/components/combobox.tsx +0 -716
- package/src/components/confirm-context.ts +0 -7
- package/src/components/confirm-dialog-labels.ts +0 -13
- package/src/components/confirm-dialog.tsx +0 -341
- package/src/components/copy-button-labels.ts +0 -13
- package/src/components/copy-button.tsx +0 -192
- package/src/components/country-select-labels.ts +0 -11
- package/src/components/country-select.tsx +0 -539
- package/src/components/currency-option-list.tsx +0 -188
- package/src/components/currency-select.tsx +0 -343
- package/src/components/danger-confirm-labels.ts +0 -20
- package/src/components/danger-confirm.tsx +0 -987
- package/src/components/data-table-cells.tsx +0 -118
- package/src/components/data-table-column-settings.tsx +0 -198
- package/src/components/data-table-filter-popover.tsx +0 -289
- package/src/components/data-table-filters.ts +0 -315
- package/src/components/data-table-fit.ts +0 -301
- package/src/components/data-table-groups.tsx +0 -288
- package/src/components/data-table-head.tsx +0 -280
- package/src/components/data-table-labels.ts +0 -198
- package/src/components/data-table-leading-row.tsx +0 -58
- package/src/components/data-table-mobile.tsx +0 -1117
- package/src/components/data-table-pagination.tsx +0 -202
- package/src/components/data-table-resize.ts +0 -188
- package/src/components/data-table-row-actions.tsx +0 -302
- package/src/components/data-table-row.tsx +0 -496
- package/src/components/data-table-selection.ts +0 -71
- package/src/components/data-table-shared.tsx +0 -287
- package/src/components/data-table-sort.ts +0 -163
- package/src/components/data-table-virtual.ts +0 -576
- package/src/components/data-table.tsx +0 -2598
- package/src/components/date-field.tsx +0 -684
- package/src/components/date-format-setting.tsx +0 -64
- package/src/components/date-picker.tsx +0 -404
- package/src/components/date-range-picker.tsx +0 -518
- package/src/components/description-list-labels.ts +0 -9
- package/src/components/description-list.tsx +0 -386
- package/src/components/dialog-frame-labels.ts +0 -7
- package/src/components/dialog-frame.tsx +0 -284
- package/src/components/disclosure.tsx +0 -476
- package/src/components/dropdown.tsx +0 -461
- package/src/components/empty-state.tsx +0 -136
- package/src/components/entity-combobox.tsx +0 -422
- package/src/components/error-boundary-labels.ts +0 -20
- package/src/components/error-boundary.tsx +0 -675
- package/src/components/facing-pair.ts +0 -93
- package/src/components/field-base-labels.ts +0 -20
- package/src/components/field-base.tsx +0 -656
- package/src/components/field-parts.tsx +0 -825
- package/src/components/field-strip.tsx +0 -129
- package/src/components/field.tsx +0 -206
- package/src/components/file-button.tsx +0 -295
- package/src/components/file-dropzone.tsx +0 -559
- package/src/components/floating-panel-labels.ts +0 -10
- package/src/components/floating-panel.tsx +0 -828
- package/src/components/focus-ring.ts +0 -16
- package/src/components/form-actions-labels.ts +0 -11
- package/src/components/form-actions.tsx +0 -578
- package/src/components/full-bleed-dialog.tsx +0 -294
- package/src/components/grouped-picker.tsx +0 -184
- package/src/components/help-popover.tsx +0 -117
- package/src/components/hover-menu.tsx +0 -343
- package/src/components/iban-input-labels.ts +0 -14
- package/src/components/iban-input.tsx +0 -236
- package/src/components/icon-button.tsx +0 -959
- package/src/components/icon-picker-labels.ts +0 -13
- package/src/components/icon-picker.tsx +0 -232
- package/src/components/image-grid-labels.ts +0 -11
- package/src/components/image-grid.tsx +0 -202
- package/src/components/inline-confirm.tsx +0 -116
- package/src/components/inline-edit-field-labels.ts +0 -11
- package/src/components/inline-edit-field.tsx +0 -552
- package/src/components/inline-entity-combobox.tsx +0 -849
- package/src/components/input.tsx +0 -394
- package/src/components/jump-calendar.tsx +0 -265
- package/src/components/language-select.tsx +0 -93
- package/src/components/legal-labels.ts +0 -105
- package/src/components/legal-page.tsx +0 -711
- package/src/components/legal.tsx +0 -668
- package/src/components/lightbox-labels.ts +0 -18
- package/src/components/lightbox.tsx +0 -399
- package/src/components/line-items-labels.ts +0 -14
- package/src/components/line-items.tsx +0 -602
- package/src/components/list-labels.ts +0 -12
- package/src/components/list.tsx +0 -870
- package/src/components/loading-state.tsx +0 -78
- package/src/components/measured-grid-labels.ts +0 -25
- package/src/components/measured-grid.tsx +0 -837
- package/src/components/menu-item.tsx +0 -241
- package/src/components/mini-calendar-labels.ts +0 -17
- package/src/components/mini-calendar.tsx +0 -792
- package/src/components/modal.tsx +0 -534
- package/src/components/money-draft.ts +0 -83
- package/src/components/money-field.tsx +0 -76
- package/src/components/month-grid.tsx +0 -229
- package/src/components/month-picker-labels.ts +0 -22
- package/src/components/month-picker.tsx +0 -1087
- package/src/components/multi-entity-combobox.tsx +0 -369
- package/src/components/multi-select.tsx +0 -376
- package/src/components/nav-pills.tsx +0 -198
- package/src/components/number-field.tsx +0 -327
- package/src/components/number-input.tsx +0 -559
- package/src/components/numeric-field.ts +0 -169
- package/src/components/numpad-sheet.tsx +0 -285
- package/src/components/one-time-code-input.tsx +0 -270
- package/src/components/page-contents-labels.ts +0 -9
- package/src/components/page-contents.tsx +0 -282
- package/src/components/page-header-context.ts +0 -8
- package/src/components/page-header.tsx +0 -298
- package/src/components/password-strength-labels.ts +0 -22
- package/src/components/password-strength.tsx +0 -241
- package/src/components/phone-input-labels.ts +0 -10
- package/src/components/phone-input.tsx +0 -282
- package/src/components/picker-sheet.tsx +0 -330
- package/src/components/pie-chart-labels.ts +0 -40
- package/src/components/pie-chart.tsx +0 -480
- package/src/components/popover-labels.ts +0 -14
- package/src/components/popover.tsx +0 -268
- package/src/components/progress-bar-labels.ts +0 -10
- package/src/components/progress-bar.tsx +0 -479
- package/src/components/qr-code.tsx +0 -76
- package/src/components/reauth-dialog-labels.ts +0 -13
- package/src/components/reauth-dialog.tsx +0 -265
- package/src/components/row-actions-labels.ts +0 -12
- package/src/components/row-actions.tsx +0 -795
- package/src/components/scroll-area.tsx +0 -123
- package/src/components/search-field.tsx +0 -192
- package/src/components/select.tsx +0 -294
- package/src/components/separator.tsx +0 -33
- package/src/components/series-chart-axes.ts +0 -342
- package/src/components/series-chart-budget.ts +0 -150
- package/src/components/series-chart-labels.ts +0 -33
- package/src/components/series-chart-thin.ts +0 -180
- package/src/components/series-chart-ticks.ts +0 -194
- package/src/components/series-chart.tsx +0 -1906
- package/src/components/server-wake-labels.ts +0 -11
- package/src/components/server-wake.tsx +0 -129
- package/src/components/settings-fields.tsx +0 -237
- package/src/components/share-card-labels.ts +0 -30
- package/src/components/share-card.tsx +0 -675
- package/src/components/signature-pad-labels.ts +0 -24
- package/src/components/signature-pad.tsx +0 -747
- package/src/components/signed-amount-labels.ts +0 -10
- package/src/components/signed-amount.tsx +0 -336
- package/src/components/skeleton.tsx +0 -80
- package/src/components/slider.tsx +0 -338
- package/src/components/sparkline-labels.ts +0 -14
- package/src/components/sparkline.tsx +0 -322
- package/src/components/spinner.tsx +0 -81
- package/src/components/stat-tile-labels.ts +0 -15
- package/src/components/stat-tile.tsx +0 -754
- package/src/components/status-dot.tsx +0 -170
- package/src/components/swatch-picker-labels.ts +0 -10
- package/src/components/swatch-picker.tsx +0 -283
- package/src/components/swipeable-row.tsx +0 -386
- package/src/components/switch.tsx +0 -273
- package/src/components/table-skeleton.tsx +0 -136
- package/src/components/table.tsx +0 -647
- package/src/components/tabs-labels.ts +0 -13
- package/src/components/tabs.tsx +0 -693
- package/src/components/text-link.tsx +0 -359
- package/src/components/text.tsx +0 -150
- package/src/components/textarea.tsx +0 -330
- package/src/components/tile-radio.tsx +0 -332
- package/src/components/time-input.tsx +0 -121
- package/src/components/toast-labels.ts +0 -12
- package/src/components/toast.tsx +0 -519
- package/src/components/toggle-group.tsx +0 -752
- package/src/components/toggle-legend.tsx +0 -394
- package/src/components/tooltip.tsx +0 -1149
- package/src/components/translation-review-editor.tsx +0 -290
- package/src/components/translation-review-labels.ts +0 -181
- package/src/components/translation-review-parts.tsx +0 -272
- package/src/components/translation-review.tsx +0 -1240
- package/src/components/tree-view.tsx +0 -589
- package/src/components/treemap-labels.ts +0 -47
- package/src/components/treemap-layout.ts +0 -210
- package/src/components/treemap.tsx +0 -1184
- package/src/components/trigger-aria.ts +0 -44
- package/src/components/use-anchor-dir.ts +0 -20
- package/src/components/use-mobile-reveal.ts +0 -62
- package/src/components/use-table-state.ts +0 -753
- package/src/components/user-avatar.tsx +0 -116
- package/src/components/wizard-stepper.tsx +0 -42
- package/src/components/write-lock-labels.ts +0 -10
- package/src/components/write-lock.tsx +0 -253
- package/src/currencies.ts +0 -90
- package/src/data-table.ts +0 -42
- package/src/demo/demo-banner.tsx +0 -153
- package/src/demo/demo-countdown.ts +0 -136
- package/src/demo/demo-ended.tsx +0 -90
- package/src/demo/demo-labels.ts +0 -78
- package/src/demo/demo-session.ts +0 -32
- package/src/demo/demo-start.tsx +0 -156
- package/src/eslint/index.ts +0 -161
- package/src/eslint/role-utilities.generated.ts +0 -146
- package/src/eslint/role-utilities.ts +0 -233
- package/src/feedback/feedback-attachment-download.tsx +0 -77
- package/src/feedback/feedback-attachment-labels.ts +0 -37
- package/src/feedback/feedback-attachment.tsx +0 -1239
- package/src/feedback/feedback-capture.ts +0 -287
- package/src/feedback/feedback-comment-thread.tsx +0 -353
- package/src/feedback/feedback-context-labels.ts +0 -11
- package/src/feedback/feedback-context.tsx +0 -245
- package/src/feedback/feedback-crash.ts +0 -547
- package/src/feedback/feedback-diagnostics.tsx +0 -41
- package/src/feedback/feedback-dialog-labels.ts +0 -29
- package/src/feedback/feedback-dialog.tsx +0 -452
- package/src/feedback/feedback-entry-file.tsx +0 -150
- package/src/feedback/feedback-inbox.tsx +0 -552
- package/src/feedback/feedback-labels.ts +0 -144
- package/src/feedback/feedback-menu-labels.ts +0 -12
- package/src/feedback/feedback-menu.tsx +0 -177
- package/src/feedback/feedback-mutation.ts +0 -20
- package/src/feedback/feedback-page-link.ts +0 -90
- package/src/feedback/feedback-public-labels.ts +0 -81
- package/src/feedback/feedback-public-list.tsx +0 -524
- package/src/feedback/feedback-public-switch.tsx +0 -102
- package/src/feedback/feedback-public-types.ts +0 -101
- package/src/feedback/feedback-record.ts +0 -428
- package/src/feedback/feedback-replies-context.ts +0 -9
- package/src/feedback/feedback-replies.tsx +0 -343
- package/src/feedback/feedback-rework-entry-chip.tsx +0 -18
- package/src/feedback/feedback-row-detail-labels.ts +0 -31
- package/src/feedback/feedback-row-detail.tsx +0 -871
- package/src/feedback/feedback-status-undo.ts +0 -109
- package/src/feedback/feedback-submit-dialog.tsx +0 -131
- package/src/feedback/feedback-submit.tsx +0 -270
- package/src/feedback/feedback-swipe.tsx +0 -192
- package/src/feedback/feedback-table-labels.ts +0 -27
- package/src/feedback/feedback-table.tsx +0 -912
- package/src/feedback/feedback-thread-labels.ts +0 -22
- package/src/feedback/feedback-thread-parts-labels.ts +0 -41
- package/src/feedback/feedback-thread.tsx +0 -905
- package/src/feedback/feedback-vocabulary.ts +0 -263
- package/src/feedback/feedback-vote-button.tsx +0 -124
- package/src/feedback.ts +0 -116
- package/src/hooks/use-anchored-panel.ts +0 -396
- package/src/hooks/use-anchored-rect.ts +0 -77
- package/src/hooks/use-announce.ts +0 -85
- package/src/hooks/use-authed-src.ts +0 -167
- package/src/hooks/use-body-scroll-lock.ts +0 -119
- package/src/hooks/use-breakpoint.ts +0 -133
- package/src/hooks/use-close-transition.ts +0 -107
- package/src/hooks/use-copy-to-clipboard.ts +0 -122
- package/src/hooks/use-debounce.ts +0 -114
- package/src/hooks/use-dismiss.ts +0 -371
- package/src/hooks/use-document-title.ts +0 -33
- package/src/hooks/use-file-drop.ts +0 -121
- package/src/hooks/use-file-picker-labels.ts +0 -28
- package/src/hooks/use-file-picker.tsx +0 -359
- package/src/hooks/use-focus-trap.ts +0 -199
- package/src/hooks/use-hotkey.ts +0 -212
- package/src/hooks/use-large-text.ts +0 -41
- package/src/hooks/use-long-press.ts +0 -140
- package/src/hooks/use-media-query.ts +0 -39
- package/src/hooks/use-mounted.ts +0 -39
- package/src/hooks/use-noindex.ts +0 -37
- package/src/hooks/use-overlay-history.ts +0 -714
- package/src/hooks/use-row-swipe.ts +0 -207
- package/src/hooks/use-search-param-state.ts +0 -434
- package/src/hooks/use-windowed-rows.ts +0 -225
- package/src/i18n/defaults.ts +0 -267
- package/src/i18n/german.ts +0 -2059
- package/src/i18n/kit-labels.tsx +0 -1003
- package/src/i18n/languages.ts +0 -349
- package/src/i18n/locales/de-CH.ts +0 -24
- package/src/i18n/locales/en.ts +0 -267
- package/src/i18n/locales/es.ts +0 -1999
- package/src/i18n/locales/fr.ts +0 -2037
- package/src/i18n/locales/hu.ts +0 -2004
- package/src/i18n/locales/it.ts +0 -2014
- package/src/i18n/locales/zh.ts +0 -1912
- package/src/i18n/plurals.ts +0 -86
- package/src/i18n/review.ts +0 -475
- package/src/i18n/shared-labels.ts +0 -138
- package/src/i18n/swiss.ts +0 -29
- package/src/index.ts +0 -1191
- package/src/landing/access.ts +0 -93
- package/src/landing/landing-actions.tsx +0 -97
- package/src/landing/landing-labels.ts +0 -59
- package/src/landing/landing-sections.tsx +0 -341
- package/src/landing/page-seo.ts +0 -261
- package/src/landing/public-header.tsx +0 -121
- package/src/landing/public-page.tsx +0 -106
- package/src/landing/routing.tsx +0 -225
- package/src/lib/broadcast.ts +0 -52
- package/src/lib/calc.ts +0 -323
- package/src/lib/chip-edge-snap.ts +0 -212
- package/src/lib/clipboard-minus.ts +0 -107
- package/src/lib/clipping.ts +0 -34
- package/src/lib/cn.ts +0 -28
- package/src/lib/column-mapping.ts +0 -234
- package/src/lib/countries.ts +0 -91
- package/src/lib/data-attributes.ts +0 -14
- package/src/lib/date-format.ts +0 -227
- package/src/lib/dates.ts +0 -288
- package/src/lib/day-format.ts +0 -96
- package/src/lib/decimal-marks.ts +0 -108
- package/src/lib/describe-failure.ts +0 -18
- package/src/lib/device-settings.ts +0 -147
- package/src/lib/direction.ts +0 -74
- package/src/lib/document-navigation.ts +0 -17
- package/src/lib/document-title.ts +0 -41
- package/src/lib/download.ts +0 -172
- package/src/lib/float-clearance.ts +0 -70
- package/src/lib/floating-stack.ts +0 -70
- package/src/lib/focus-left.ts +0 -156
- package/src/lib/format.ts +0 -585
- package/src/lib/http-status.ts +0 -38
- package/src/lib/iban.ts +0 -251
- package/src/lib/ime.ts +0 -24
- package/src/lib/intl-cache.ts +0 -27
- package/src/lib/iso-day.ts +0 -13
- package/src/lib/lazy-with-fallback.ts +0 -82
- package/src/lib/logger.ts +0 -69
- package/src/lib/minus.ts +0 -50
- package/src/lib/path-pattern.ts +0 -55
- package/src/lib/person-name.ts +0 -155
- package/src/lib/phone.ts +0 -208
- package/src/lib/plain-text.ts +0 -22
- package/src/lib/presence.ts +0 -18
- package/src/lib/qr-encode.ts +0 -444
- package/src/lib/quiet-focus.ts +0 -32
- package/src/lib/reduced-motion.ts +0 -22
- package/src/lib/refs.ts +0 -22
- package/src/lib/round.ts +0 -43
- package/src/lib/safe-storage.ts +0 -119
- package/src/lib/server-wake.ts +0 -315
- package/src/lib/session-refresh.ts +0 -472
- package/src/lib/share-format.ts +0 -18
- package/src/lib/status-tone.ts +0 -43
- package/src/lib/strip-fade.ts +0 -287
- package/src/lib/table-text.ts +0 -554
- package/src/lib/text-case.ts +0 -19
- package/src/lib/text-match.ts +0 -169
- package/src/lib/thenable.ts +0 -19
- package/src/lib/translation-review.ts +0 -769
- package/src/notifications/device-zone-report.ts +0 -67
- package/src/notifications/feedback-notification-types-labels.ts +0 -33
- package/src/notifications/feedback-notification-types.ts +0 -71
- package/src/notifications/notification-bell.tsx +0 -119
- package/src/notifications/notification-inbox.tsx +0 -309
- package/src/notifications/notification-parts.tsx +0 -81
- package/src/notifications/notification-types-setting.tsx +0 -406
- package/src/notifications/notification-types.ts +0 -89
- package/src/notifications/notifications-labels.ts +0 -287
- package/src/notifications/push-device-setting.tsx +0 -230
- package/src/notifications/push-devices-setting.tsx +0 -374
- package/src/notifications/push-worker.ts +0 -168
- package/src/notifications/quiet-hours-setting.tsx +0 -238
- package/src/notifications/unsubscribe-panel.tsx +0 -200
- package/src/notifications/use-push-device.ts +0 -448
- package/src/offline/local-first.ts +0 -100
- package/src/offline/pwa-update-prompt-labels.ts +0 -9
- package/src/offline/pwa-update-prompt.tsx +0 -78
- package/src/offline/query-persistence.ts +0 -391
- package/src/offline/service-worker-updates.ts +0 -81
- package/src/offline/shared-computer-labels.ts +0 -8
- package/src/offline/shared-computer.tsx +0 -87
- package/src/offline/sign-out-pending-dialog-labels.ts +0 -21
- package/src/offline/sign-out-pending-dialog.tsx +0 -135
- package/src/offline.ts +0 -37
- package/src/push-worker.ts +0 -25
- package/src/rhf/fields.tsx +0 -2187
- package/src/rhf/form-core.tsx +0 -324
- package/src/rhf/form.tsx +0 -12
- package/src/rhf/line-items.tsx +0 -135
- package/src/rhf/use-rhf-wizard-step.ts +0 -104
- package/src/rhf.ts +0 -21
- package/src/search/command-palette-labels.ts +0 -16
- package/src/search/command-palette.tsx +0 -624
- package/src/search/global-search-labels.ts +0 -13
- package/src/search/global-search.tsx +0 -660
- package/src/search/search-index.ts +0 -283
- package/src/search/use-command-key.ts +0 -23
- package/src/search.ts +0 -14
- package/src/settings/device-reset-setting-labels.ts +0 -20
- package/src/settings/device-reset-setting.tsx +0 -116
- package/src/settings/settings-card-classes.ts +0 -11
- package/src/settings/settings-catalogue.ts +0 -150
- package/src/settings/settings-context.ts +0 -33
- package/src/settings/settings-heading.tsx +0 -67
- package/src/settings/settings-labels.ts +0 -87
- package/src/settings/settings-layout.tsx +0 -471
- package/src/settings/settings-section.tsx +0 -108
- package/src/settings/use-account-appearance.ts +0 -148
- package/src/settings/use-account-language.ts +0 -146
- package/src/settings/use-settings-focus.ts +0 -128
- package/src/settings/use-settings-route.ts +0 -258
- package/src/shell/account-menu-language.tsx +0 -130
- package/src/shell/account-menu-text-size.tsx +0 -80
- package/src/shell/admin-menu.tsx +0 -183
- package/src/shell/app-shell-labels.ts +0 -11
- package/src/shell/app-shell.tsx +0 -1560
- package/src/shell/auth-layout.tsx +0 -186
- package/src/shell/company-switcher-labels.ts +0 -13
- package/src/shell/company-switcher.tsx +0 -136
- package/src/shell/dev-menu.tsx +0 -257
- package/src/shell/fill-height.tsx +0 -45
- package/src/shell/language-code.ts +0 -5
- package/src/shell/option-switcher-menu.tsx +0 -84
- package/src/shell/sync-status-indicator.tsx +0 -303
- package/src/shell/top-bar-actions.tsx +0 -87
- package/src/shell/top-bar-brand.tsx +0 -78
- package/src/shell/top-bar-parts-labels.ts +0 -148
- package/src/shell/top-bar.tsx +0 -40
- package/src/shell/topbar-action-menu.tsx +0 -567
- package/src/shell/topbar-controls.tsx +0 -269
- package/src/shell/tour-menu.tsx +0 -187
- package/src/shell.ts +0 -108
- package/src/sync/db.ts +0 -129
- package/src/sync/engine.ts +0 -1011
- package/src/sync/hooks.ts +0 -98
- package/src/sync/testing.ts +0 -73
- package/src/sync/wire.ts +0 -61
- package/src/sync.ts +0 -37
- package/src/table-text.ts +0 -8
- package/src/testing/css-variables.generated.ts +0 -112
- package/src/testing/css-variables.ts +0 -189
- package/src/testing/index.ts +0 -29
- package/src/testing/react.ts +0 -58
- package/src/testing/tour.ts +0 -41
- package/src/testing/viewport.ts +0 -357
- package/src/theme/chart-palette.ts +0 -232
- package/src/theme/color.ts +0 -272
- package/src/theme/contrast-tokens.ts +0 -268
- package/src/theme/contrast.ts +0 -250
- package/src/theme/palette-derive.ts +0 -825
- package/src/theme/palette-presets.ts +0 -544
- package/src/theme/palette-store.ts +0 -108
- package/src/theme/text-size.ts +0 -289
- package/src/theme/theme-store.ts +0 -157
- package/src/tour/tour-catalogue-labels.ts +0 -75
- package/src/tour/tour-catalogue.tsx +0 -335
- package/src/tour/tour-dock.ts +0 -134
- package/src/tour/tour-engine.ts +0 -37
- package/src/tour/tour-gates.ts +0 -218
- package/src/tour/tour-guide-button.tsx +0 -64
- package/src/tour/tour-guide-labels.ts +0 -15
- package/src/tour/tour-info.ts +0 -144
- package/src/tour/tour-labels.ts +0 -23
- package/src/tour/tour-overlay.tsx +0 -1170
- package/src/tour/tour.tsx +0 -750
- package/src/tour/use-tour-progress.ts +0 -671
- package/src/tour/use-tour-url-sync.ts +0 -266
- package/src/tour.ts +0 -21
- package/src/vite-env.d.ts +0 -23
- package/src/wizard/stepper-nav.tsx +0 -360
- package/src/wizard/types.ts +0 -275
- package/src/wizard/use-wizard.ts +0 -560
- package/src/wizard/validation.ts +0 -39
- package/src/wizard/wizard-context.tsx +0 -74
- package/src/wizard/wizard-labels.ts +0 -29
- package/src/wizard/wizard-step.tsx +0 -76
- package/src/wizard/wizard-summary.tsx +0 -84
- package/src/wizard.ts +0 -15
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
|
-
import { toast } from "../components/toast";
|
|
3
|
-
import type { FeedbackStatus } from "./feedback-vocabulary";
|
|
4
|
-
import {
|
|
5
|
-
useFeedbackStatusLabels,
|
|
6
|
-
useFeedbackToastLabels,
|
|
7
|
-
type FeedbackStatusLabels,
|
|
8
|
-
type FeedbackToastLabels,
|
|
9
|
-
} from "./feedback-labels";
|
|
10
|
-
import type { FeedbackRecord } from "./feedback-record";
|
|
11
|
-
import type { LabelOverride } from "../i18n/kit-labels";
|
|
12
|
-
import { runMutation } from "./feedback-mutation";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* A status change that can be taken back — §4.5 of the feedback contract, lifted from
|
|
16
|
-
* keksdose's `changeStatusUndoably` (`frontend/src/features/feedback/feedback-page.tsx`,
|
|
17
|
-
* dev #587: *"Just clicked somewhere and a feedback row disappeared without knowing what
|
|
18
|
-
* I set as new status."*).
|
|
19
|
-
*
|
|
20
|
-
* An inbox is usually filtered by status, so a row whose new status falls outside the
|
|
21
|
-
* filter leaves the table the moment the change lands, with nothing on screen saying what
|
|
22
|
-
* it became. The toast says it, names the report, and offers the old status back for 8 s
|
|
23
|
-
* (the window keksdose's transactions Undo uses, feedback #184). Undo PATCHes the old
|
|
24
|
-
* status and confirms that too. kastlan and Kurvenschmiede had no Undo at all.
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/** The one PATCH a status change is: `PATCH /feedback/{id}` with `{ status }`. */
|
|
28
|
-
export interface FeedbackStatusPatch {
|
|
29
|
-
id: number;
|
|
30
|
-
status: FeedbackStatus;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The page's status mutation (0.52): **TanStack Query's `mutateAsync`** — pass
|
|
35
|
-
* `update.mutateAsync`. The toast comes when the promise resolves, which it does for every
|
|
36
|
-
* call (refactor audit 2026-10-30, FLW-3). A hand-written one returns a promise that
|
|
37
|
-
* resolves once the PATCH has landed and rejects when it failed.
|
|
38
|
-
*
|
|
39
|
-
* Failure is the mutation's own business: its `onError` toasts the server's `detail`,
|
|
40
|
-
* else `feedbackToast.updateFailed` (§4.4) — this hook adds no second error toast, and
|
|
41
|
-
* catches the rejection.
|
|
42
|
-
*/
|
|
43
|
-
export type FeedbackStatusMutateAsync = (patch: FeedbackStatusPatch) => Promise<unknown>;
|
|
44
|
-
|
|
45
|
-
/** What the change needs to know about the row: which one, what it is called in the
|
|
46
|
-
* toast, and where it stood (the status Undo goes back to). */
|
|
47
|
-
export type FeedbackStatusRow = Pick<FeedbackRecord, "id" | "title" | "status">;
|
|
48
|
-
|
|
49
|
-
/** Set `row` to `status`, with the Undo toast. A no-op when it is already there. */
|
|
50
|
-
export type FeedbackStatusChange = (row: FeedbackStatusRow, status: FeedbackStatus) => void;
|
|
51
|
-
|
|
52
|
-
export interface FeedbackStatusUndoOptions {
|
|
53
|
-
/** Over the `feedbackToast` namespace (the toast's words). */
|
|
54
|
-
labels?: LabelOverride<FeedbackToastLabels>;
|
|
55
|
-
/** Over the `feedbackStatus` namespace (the status names inside them). */
|
|
56
|
-
statusLabels?: Partial<FeedbackStatusLabels>;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/** How long the Undo stays reachable: 8 s, keksdose's window (feedback #184). */
|
|
60
|
-
export const FEEDBACK_UNDO_DURATION = 8000;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* The undoable status change — for the table's status cell, the row detail's pills and
|
|
64
|
-
* the phone swipes alike (§4.5, §7.10: swipes included, Marcel 2026-10-04 — keksdose's
|
|
65
|
-
* swipe commits go through its `changeStatusUndoably` too). Wire every one of them
|
|
66
|
-
* through the function this returns:
|
|
67
|
-
*
|
|
68
|
-
* ```tsx
|
|
69
|
-
* const update = useMutation({ mutationFn: api.updateFeedback, onError: … });
|
|
70
|
-
* const changeStatus = useFeedbackStatusUndo(update.mutateAsync);
|
|
71
|
-
* <FeedbackStatusTransitions … onPick={(status) => changeStatus(row, status)} />
|
|
72
|
-
* ```
|
|
73
|
-
*
|
|
74
|
-
* Give it the PAGE's mutation, not one a row owns: a row the new status filters out
|
|
75
|
-
* unmounts before the PATCH answers.
|
|
76
|
-
*
|
|
77
|
-
* The flow: PATCH `{ id, status }` → once it has landed a success toast
|
|
78
|
-
* `statusChanged(newName, title)` with the action `statusUndo`, 8 s → Undo PATCHes
|
|
79
|
-
* `{ id, status: previous }` → once that has landed `statusRestored(previousName, title)`.
|
|
80
|
-
* Each change waits for its OWN answer, so two changes in flight each get their toast.
|
|
81
|
-
*
|
|
82
|
-
* `update.mutate`, the callback form, went in 0.53 (deprecated in 0.52): with it a second
|
|
83
|
-
* change before the first answered lost the first one's Undo.
|
|
84
|
-
*/
|
|
85
|
-
export function useFeedbackStatusUndo(
|
|
86
|
-
mutate: FeedbackStatusMutateAsync,
|
|
87
|
-
{ labels, statusLabels }: FeedbackStatusUndoOptions = {},
|
|
88
|
-
): FeedbackStatusChange {
|
|
89
|
-
const words = useFeedbackToastLabels(labels);
|
|
90
|
-
const names = useFeedbackStatusLabels(statusLabels);
|
|
91
|
-
return useCallback<FeedbackStatusChange>(
|
|
92
|
-
(row, status) => {
|
|
93
|
-
const { id, title, status: previous } = row;
|
|
94
|
-
if (status === previous) return;
|
|
95
|
-
const nameOf = (value: FeedbackStatus) => names[value] ?? value;
|
|
96
|
-
runMutation(mutate, { id, status }, () => {
|
|
97
|
-
toast.undo(words.statusChanged(nameOf(status), title), {
|
|
98
|
-
label: words.statusUndo,
|
|
99
|
-
duration: FEEDBACK_UNDO_DURATION,
|
|
100
|
-
onUndo: () =>
|
|
101
|
-
runMutation(mutate, { id, status: previous }, () => {
|
|
102
|
-
toast.success(words.statusRestored(nameOf(previous), title));
|
|
103
|
-
}),
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
},
|
|
107
|
-
[mutate, words, names],
|
|
108
|
-
);
|
|
109
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { toast } from "../components/toast";
|
|
2
|
-
import { captureAppScreenshot } from "./feedback-capture";
|
|
3
|
-
import { FeedbackContextBox, feedbackContext, type FeedbackSubmitter } from "./feedback-context";
|
|
4
|
-
import { FeedbackDialog, type FeedbackMultipleSubmission } from "./feedback-dialog";
|
|
5
|
-
import { DEFAULT_FEEDBACK_DIALOG_LABELS } from "./feedback-dialog-labels";
|
|
6
|
-
import { useKitLabels } from "../i18n/kit-labels";
|
|
7
|
-
import { useFeedbackCategoryLabels, useFeedbackToastLabels } from "./feedback-labels";
|
|
8
|
-
import {
|
|
9
|
-
DEFAULT_MAX_ATTACHMENTS,
|
|
10
|
-
FEEDBACK_ATTACHMENT_ACCEPT,
|
|
11
|
-
FEEDBACK_PICKABLE_CATEGORIES,
|
|
12
|
-
type FeedbackContext,
|
|
13
|
-
type FeedbackEnvironment,
|
|
14
|
-
} from "./feedback-record";
|
|
15
|
-
import type { FeedbackSubmitOpenOptions } from "./feedback-submit";
|
|
16
|
-
import type { FeedbackCategory } from "./feedback-vocabulary";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* The open half of `useFeedbackSubmit`: the dialog it draws, with the context box and
|
|
20
|
-
* everything that only exists while somebody is filing a report.
|
|
21
|
-
*
|
|
22
|
-
* A module of its own so it can load LATE (0.34, MOD-1 of the refactor audit 2026-10).
|
|
23
|
-
* Every app mounts the hook in its top bar; this — the attachment field, the modal, the
|
|
24
|
-
* context box, the capture — was ~11 kB gzip of each app's entry chunk, for a dialog most
|
|
25
|
-
* sessions never open. feedback-submit.tsx reaches it only through a literal relative
|
|
26
|
-
* `import()`, so the library build keeps it a module of its own (`bundle: false`) and an
|
|
27
|
-
* app's bundler makes it a chunk of its own.
|
|
28
|
-
*
|
|
29
|
-
* Internal, and not in the barrel: nothing but that `import()` should reach it. The hook
|
|
30
|
-
* keeps the state — open, category, the URL and whether it goes along, the send in
|
|
31
|
-
* flight — and this draws it.
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
/** What `useFeedbackSubmit` hands its lazily loaded dialog. */
|
|
35
|
-
export interface FeedbackSubmitDialogProps {
|
|
36
|
-
onClose: () => void;
|
|
37
|
-
category: FeedbackCategory;
|
|
38
|
-
onCategoryChange: (category: FeedbackCategory) => void;
|
|
39
|
-
submitting: boolean;
|
|
40
|
-
/** The form, and the `context` built from the same values the box showed. */
|
|
41
|
-
onSubmit: (data: FeedbackMultipleSubmission<FeedbackCategory>, context: FeedbackContext) => void | Promise<void>;
|
|
42
|
-
user?: FeedbackSubmitter | null;
|
|
43
|
-
/** `location.href` when the dialog opened. */
|
|
44
|
-
url: string;
|
|
45
|
-
attachUrl: boolean;
|
|
46
|
-
onAttachUrlChange: (attachUrl: boolean) => void;
|
|
47
|
-
environment?: FeedbackEnvironment | (string & {});
|
|
48
|
-
version?: string;
|
|
49
|
-
/** `UseFeedbackSubmitOptions.capture`, as the app passed it. */
|
|
50
|
-
capture?: false | (() => Promise<File | null>);
|
|
51
|
-
/** `UseFeedbackSubmitOptions.publicNotice` (0.38): the line under the body. */
|
|
52
|
-
publicNotice?: boolean;
|
|
53
|
-
/** `open(category, options)`'s, taken when it opened (keksdose live #481): the box
|
|
54
|
-
* shows the diagnostics and the report carries them; the title and body prefill. */
|
|
55
|
-
opened?: FeedbackSubmitOpenOptions;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** `FeedbackDialog` as `useFeedbackSubmit` settles it — see the hook for what it settles. */
|
|
59
|
-
export function FeedbackSubmitDialog({
|
|
60
|
-
onClose,
|
|
61
|
-
category,
|
|
62
|
-
onCategoryChange,
|
|
63
|
-
submitting,
|
|
64
|
-
onSubmit,
|
|
65
|
-
user,
|
|
66
|
-
url,
|
|
67
|
-
attachUrl,
|
|
68
|
-
onAttachUrlChange,
|
|
69
|
-
environment,
|
|
70
|
-
version,
|
|
71
|
-
capture,
|
|
72
|
-
publicNotice = false,
|
|
73
|
-
opened: { diagnostics, title, body } = {},
|
|
74
|
-
}: FeedbackSubmitDialogProps) {
|
|
75
|
-
const toastText = useFeedbackToastLabels();
|
|
76
|
-
const dialogText = useKitLabels("feedbackDialog", DEFAULT_FEEDBACK_DIALOG_LABELS);
|
|
77
|
-
const categoryLabels = useFeedbackCategoryLabels();
|
|
78
|
-
|
|
79
|
-
const onCaptureScreenshot =
|
|
80
|
-
capture === false
|
|
81
|
-
? undefined
|
|
82
|
-
: async () => {
|
|
83
|
-
try {
|
|
84
|
-
return await (capture ?? (() => captureAppScreenshot()))();
|
|
85
|
-
} catch {
|
|
86
|
-
toast.error(toastText.captureFailed);
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
return (
|
|
92
|
-
<FeedbackDialog
|
|
93
|
-
open
|
|
94
|
-
onClose={onClose}
|
|
95
|
-
categories={FEEDBACK_PICKABLE_CATEGORIES.map((value) => ({ value, label: categoryLabels[value] }))}
|
|
96
|
-
category={category}
|
|
97
|
-
onCategoryChange={onCategoryChange}
|
|
98
|
-
submitting={submitting}
|
|
99
|
-
attachments="multiple"
|
|
100
|
-
maxAttachments={DEFAULT_MAX_ATTACHMENTS}
|
|
101
|
-
requireBody={false}
|
|
102
|
-
attachmentAccept={FEEDBACK_ATTACHMENT_ACCEPT}
|
|
103
|
-
onAttachmentError={(kind, info) =>
|
|
104
|
-
toast.error(
|
|
105
|
-
kind === "type"
|
|
106
|
-
? toastText.attachmentUnsupported
|
|
107
|
-
: kind === "size"
|
|
108
|
-
? toastText.attachmentTooLarge
|
|
109
|
-
: // More files at once than there was room for: the surplus was dropped, the
|
|
110
|
-
// rest kept. The count is how many fit, as keksdose says it.
|
|
111
|
-
toastText.attachmentTooMany(info.max ?? DEFAULT_MAX_ATTACHMENTS),
|
|
112
|
-
)
|
|
113
|
-
}
|
|
114
|
-
onCaptureScreenshot={onCaptureScreenshot}
|
|
115
|
-
publicNotice={publicNotice ? (dialogText.publicNotice ?? DEFAULT_FEEDBACK_DIALOG_LABELS.publicNotice) : undefined}
|
|
116
|
-
defaultTitle={title}
|
|
117
|
-
defaultBody={body}
|
|
118
|
-
// The context is read off the very values the box below shows (§3.2).
|
|
119
|
-
onSubmit={(data) => onSubmit(data, feedbackContext({ user, attachUrl, url, environment, version, diagnostics }))}
|
|
120
|
-
contextSlot={
|
|
121
|
-
<FeedbackContextBox
|
|
122
|
-
user={user}
|
|
123
|
-
url={url}
|
|
124
|
-
attachUrl={attachUrl}
|
|
125
|
-
onAttachUrlChange={onAttachUrlChange}
|
|
126
|
-
diagnostics={diagnostics}
|
|
127
|
-
/>
|
|
128
|
-
}
|
|
129
|
-
/>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import { Suspense, useLayoutEffect, useRef, useState } from "react";
|
|
2
|
-
import type { ReactNode } from "react";
|
|
3
|
-
import { toast } from "../components/toast";
|
|
4
|
-
import { lazyWithFallback } from "../lib/lazy-with-fallback";
|
|
5
|
-
// Types only, gone from the built module: the dialog's modules load with the dialog.
|
|
6
|
-
import type { FeedbackSubmitter } from "./feedback-context";
|
|
7
|
-
import type { FeedbackSubmitDialogProps } from "./feedback-submit-dialog";
|
|
8
|
-
import type { FeedbackMultipleSubmission } from "./feedback-dialog";
|
|
9
|
-
import { useFeedbackToastLabels } from "./feedback-labels";
|
|
10
|
-
import { FEEDBACK_PICKABLE_CATEGORIES, type FeedbackContext, type FeedbackEnvironment } from "./feedback-record";
|
|
11
|
-
import type { FeedbackCategory } from "./feedback-vocabulary";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* The dialog, loaded when it is first opened rather than with the top bar that mounts the
|
|
15
|
-
* hook (0.34, MOD-1 of the refactor audit 2026-10; see feedback-submit-dialog.tsx). A
|
|
16
|
-
* LITERAL relative `import()`, as the catalogue loaders are (i18n/languages.ts): the
|
|
17
|
-
* library build keeps the module its own (`bundle: false`), and a path an app's bundler
|
|
18
|
-
* can read is a chunk it can split off.
|
|
19
|
-
*
|
|
20
|
-
* A fetch that fails — a tab left open across a deploy, offline — closes the dialog
|
|
21
|
-
* rather than throwing (0.52 code review, tour.tsx): the hook lives in the top bar, above
|
|
22
|
-
* the routes' error boundaries, so the rejected import took the whole shell down. The
|
|
23
|
-
* next open fetches again.
|
|
24
|
-
*/
|
|
25
|
-
const LazySubmitDialog = lazyWithFallback(
|
|
26
|
-
() => import("./feedback-submit-dialog").then((module) => module.FeedbackSubmitDialog),
|
|
27
|
-
SubmitDialogUnavailable,
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
function SubmitDialogUnavailable({ onClose }: FeedbackSubmitDialogProps) {
|
|
31
|
-
useLayoutEffect(onClose, [onClose]);
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* `FeedbackCreate` — the body of `POST /feedback` (keksdose `schemas/feedback.py:25`, §3.4
|
|
37
|
-
* of docs/feedback-harmonization.md), as {@link useFeedbackSubmit} hands it to the app's
|
|
38
|
-
* `create`.
|
|
39
|
-
*/
|
|
40
|
-
export interface FeedbackCreatePayload {
|
|
41
|
-
/** Trimmed; never blank (the dialog will not send a subject of spaces). */
|
|
42
|
-
title: string;
|
|
43
|
-
/** `""` when the reporter wrote nothing or only whitespace — the server stores `""`. */
|
|
44
|
-
body: string;
|
|
45
|
-
/** Never `CRASH` — the server answers that with a 422 (§3.4). */
|
|
46
|
-
category: FeedbackCategory;
|
|
47
|
-
/** §3.2, built by `feedbackContext` from what the context box showed. */
|
|
48
|
-
context: FeedbackContext;
|
|
49
|
-
/** The captured screenshot's upload URL, or `null`. */
|
|
50
|
-
screenshot_url: string | null;
|
|
51
|
-
/** The picked and pasted files' upload URLs, in the order they were added — `[]` when
|
|
52
|
-
* none, as keksdose sends it. At most 5. */
|
|
53
|
-
attachment_urls: string[];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface UseFeedbackSubmitOptions<R = unknown> {
|
|
57
|
-
/**
|
|
58
|
-
* `POST /feedback/attachments` for ONE file → its URL (§3.3) — the app's authed client.
|
|
59
|
-
* Every file goes up BEFORE the report is created, so a row never names a file that did
|
|
60
|
-
* not arrive (keksdose `use-feedback-dialog.tsx:89`); if any upload rejects, nothing is
|
|
61
|
-
* created and the failure toast says so.
|
|
62
|
-
*/
|
|
63
|
-
upload: (file: File) => Promise<string>;
|
|
64
|
-
/** `POST /feedback` with the payload. Whatever it resolves with reaches `onSubmitted`. */
|
|
65
|
-
create: (payload: FeedbackCreatePayload) => Promise<R>;
|
|
66
|
-
/** Who is filing — shown in the context box and sent in `context.user_*`. */
|
|
67
|
-
user?: FeedbackSubmitter | null;
|
|
68
|
-
/** `context.environment` — the app's own reading of which copy it is (keksdose
|
|
69
|
-
* `deployEnvironment()`). */
|
|
70
|
-
environment?: FeedbackEnvironment | (string & {});
|
|
71
|
-
/** `context.version` — the app build (`__APP_VERSION__`). */
|
|
72
|
-
version?: string;
|
|
73
|
-
/** The report was filed: after the "Thanks for the feedback!" toast and the close. The
|
|
74
|
-
* place to invalidate the app's feedback queries. */
|
|
75
|
-
onSubmitted?: (result: R) => void;
|
|
76
|
-
/**
|
|
77
|
-
* The failure toast's text from what `upload` or `create` rejected with — the app's own
|
|
78
|
-
* `extractApiErrorMessage(err, fallback)` (keksdose) / `apiErrorMessage` (Kurvenschmiede),
|
|
79
|
-
* so the server's `detail` wins (§3.7: a 413, a 415, keksdose's demo-session 403). Without
|
|
80
|
-
* it every failure says `feedbackToast.submitFailed`.
|
|
81
|
-
*/
|
|
82
|
-
errorMessage?: (error: unknown, fallback: string) => string;
|
|
83
|
-
/**
|
|
84
|
-
* The "Capture screenshot" button's capture. Default {@link captureAppScreenshot} of
|
|
85
|
-
* `#root`; another root is `() => captureAppScreenshot({ rootId: "app" })`. `false`
|
|
86
|
-
* hides the button — for an app that does not install the optional peer
|
|
87
|
-
* `modern-screenshot`. A rejection becomes the `captureFailed` toast.
|
|
88
|
-
*/
|
|
89
|
-
capture?: false | (() => Promise<File | null>);
|
|
90
|
-
/**
|
|
91
|
-
* The app's reports are public (0.38, docs/feedback-harmonization.md §9.2 decision 6):
|
|
92
|
-
* `true` shows **"Other users will see the title and text (never your screenshots or
|
|
93
|
-
* files)"** (`feedbackDialog.publicNotice`) under the body. keksdose and Kurvenschmiede
|
|
94
|
-
* pass it — for a viewer who passes the app's `public_viewer` — and kastlan, whose
|
|
95
|
-
* public parts are off, does not. Default `false`.
|
|
96
|
-
*/
|
|
97
|
-
publicNotice?: boolean;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* `open`'s second argument (keksdose live #481: "Report this problem" on a receipt scan
|
|
102
|
-
* that never finished, filed with the scan's bookkeeping). All of it optional, and none of
|
|
103
|
-
* it outlives the opening it was handed to.
|
|
104
|
-
*/
|
|
105
|
-
export interface FeedbackSubmitOpenOptions {
|
|
106
|
-
/**
|
|
107
|
-
* What the app knows about the thing reported — keksdose's stuck scan: its id, status,
|
|
108
|
-
* attempts, last error. Taken when the dialog opens (a shallow copy, so what the box
|
|
109
|
-
* shows is what goes, even if the app's object changes while the reporter types), shown
|
|
110
|
-
* read-only in the context box, and sent as `context.diagnostics` whatever "Attach
|
|
111
|
-
* current page URL" says: that box withholds the page, not this. Flat, short values,
|
|
112
|
-
* never the reported content itself (§3.2); the row detail shows them to the admin and
|
|
113
|
-
* the author only.
|
|
114
|
-
*/
|
|
115
|
-
diagnostics?: Readonly<Record<string, unknown>>;
|
|
116
|
-
/** The subject the form starts with; the reporter can change it. Where the app's reports
|
|
117
|
-
* are public (`publicNotice`), other users read it: what only the admin should see goes
|
|
118
|
-
* in `diagnostics`. */
|
|
119
|
-
title?: string;
|
|
120
|
-
/** The body the form starts with, as `title` is the subject's. */
|
|
121
|
-
body?: string;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export interface FeedbackSubmit {
|
|
125
|
-
/**
|
|
126
|
-
* Open the dialog on `category` — a `FeedbackMenu` row's (§4.2: "default category when
|
|
127
|
-
* opened from a row: that row's"). Without one, or with `CRASH` (never pickable), it
|
|
128
|
-
* opens on `OTHER`, the server's own default (§3.4). Each open starts a fresh form,
|
|
129
|
-
* reads `location.href` for the context box and ticks "Attach current page URL" again.
|
|
130
|
-
*
|
|
131
|
-
* `options` (0.54, keksdose live #481) is a screen's own report — `open("BUG", {
|
|
132
|
-
* diagnostics })` from "Report this problem": the diagnostics shown in the box and sent,
|
|
133
|
-
* the subject and body prefilled. An open without them starts empty and sends none.
|
|
134
|
-
*/
|
|
135
|
-
open: (category?: FeedbackCategory, options?: FeedbackSubmitOpenOptions) => void;
|
|
136
|
-
/** Close it, as Cancel does. */
|
|
137
|
-
close: () => void;
|
|
138
|
-
/**
|
|
139
|
-
* The dialog — render it once, anywhere (it portals). `null` while closed. Since 0.34
|
|
140
|
-
* its module loads when it is first opened (MOD-1), so it appears a moment after
|
|
141
|
-
* `open`: a test finds it with `await screen.findBy…`, not `getBy…`.
|
|
142
|
-
*/
|
|
143
|
-
dialog: ReactNode;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* The feedback submit dialog, wired (0.27.0, docs/feedback-harmonization.md §4.2): the
|
|
148
|
-
* one call that replaces keksdose's `use-feedback-dialog.tsx`, kastlan's `FeedbackButton`
|
|
149
|
-
* and Kurvenschmiede's `use-feedback-dialog.tsx`.
|
|
150
|
-
*
|
|
151
|
-
* ```tsx
|
|
152
|
-
* const feedback = useFeedbackSubmit({
|
|
153
|
-
* upload: (file) => feedbackApi.uploadAttachment(file),
|
|
154
|
-
* create: (payload) => feedbackApi.create(payload),
|
|
155
|
-
* user, environment: deployEnvironment(), version: __APP_VERSION__,
|
|
156
|
-
* errorMessage: extractApiErrorMessage,
|
|
157
|
-
* onSubmitted: () => qc.invalidateQueries({ queryKey: queryKeys.feedback.all }),
|
|
158
|
-
* });
|
|
159
|
-
* <FeedbackMenu onFile={feedback.open} isAdmin={user?.role === "ADMIN"} />
|
|
160
|
-
* {feedback.dialog}
|
|
161
|
-
* ```
|
|
162
|
-
*
|
|
163
|
-
* What it settles, so no app restates it:
|
|
164
|
-
*
|
|
165
|
-
* - `FeedbackDialog` in `attachments="multiple"` with `requireBody={false}` (§7.4): a
|
|
166
|
-
* subject alone is a report. One captured screenshot in its own slot plus up to 5
|
|
167
|
-
* picked or pasted files, `FEEDBACK_ATTACHMENT_ACCEPT` (images, PDF, text), 10 MB each.
|
|
168
|
-
* - The pickable categories — Bug, Idea, Question, Other, in the kit's words. `CRASH` is
|
|
169
|
-
* filed by the error boundary and is never offered (keksdose feedback #160).
|
|
170
|
-
* - The context box, built from the same values as the `context` it sends
|
|
171
|
-
* ({@link FeedbackContextBox} / `feedbackContext`), the URL read when the dialog OPENS,
|
|
172
|
-
* and the diagnostics `open` was handed then (0.54, keksdose live #481).
|
|
173
|
-
* - Upload every file, then create (keksdose `use-feedback-dialog.tsx:89`): the
|
|
174
|
-
* screenshot to `screenshot_url`, the rest to `attachment_urls`, all in parallel.
|
|
175
|
-
* - The toasts, from `feedbackToast`: filed, failed (the server's `detail` through
|
|
176
|
-
* `errorMessage`), a refused file's type, size or count, a failed capture.
|
|
177
|
-
*
|
|
178
|
-
* What stays the app's: the API client, the user, the environment and version, and what
|
|
179
|
-
* to refresh afterwards. No TanStack in here — `create` is a plain promise, so the hook
|
|
180
|
-
* runs in any app; the app's mutation, if it wants one, lives inside `create`.
|
|
181
|
-
*
|
|
182
|
-
* A failure keeps the dialog open with the draft, as keksdose's did. A dialog closed and
|
|
183
|
-
* opened again while a send is still running is NOT closed by that send's success — the
|
|
184
|
-
* new draft is somebody's next report.
|
|
185
|
-
*/
|
|
186
|
-
export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions<R>): FeedbackSubmit {
|
|
187
|
-
const { upload, create, user, environment, version, onSubmitted, errorMessage, capture, publicNotice } = options;
|
|
188
|
-
const toastText = useFeedbackToastLabels();
|
|
189
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
190
|
-
const [category, setCategory] = useState<FeedbackCategory>("OTHER");
|
|
191
|
-
const [url, setUrl] = useState("");
|
|
192
|
-
const [attachUrl, setAttachUrl] = useState(true);
|
|
193
|
-
const [opened, setOpened] = useState<FeedbackSubmitOpenOptions>({});
|
|
194
|
-
const [submitting, setSubmitting] = useState(false);
|
|
195
|
-
// Which opening a send belongs to — see "closed and opened again" above.
|
|
196
|
-
const opening = useRef(0);
|
|
197
|
-
const inFlight = useRef(false);
|
|
198
|
-
|
|
199
|
-
const open = (next?: FeedbackCategory, given?: FeedbackSubmitOpenOptions) => {
|
|
200
|
-
opening.current += 1;
|
|
201
|
-
setCategory(next && FEEDBACK_PICKABLE_CATEGORIES.includes(next) ? next : "OTHER");
|
|
202
|
-
setUrl(typeof window === "undefined" ? "" : window.location.href);
|
|
203
|
-
// Fresh every time (Kurvenschmiede use-feedback-dialog.tsx:80): a reporter who left the
|
|
204
|
-
// page out of one idea is not saying the bug report after it is unrelated too.
|
|
205
|
-
setAttachUrl(true);
|
|
206
|
-
// This opening's own, nothing of the last one's; the diagnostics copied now (#481).
|
|
207
|
-
setOpened({ ...given, diagnostics: given?.diagnostics && { ...given.diagnostics } });
|
|
208
|
-
setIsOpen(true);
|
|
209
|
-
};
|
|
210
|
-
const close = () => setIsOpen(false);
|
|
211
|
-
|
|
212
|
-
// `context` comes from the dialog, built off the values its context box shows.
|
|
213
|
-
const submit = async (data: FeedbackMultipleSubmission<FeedbackCategory>, context: FeedbackContext) => {
|
|
214
|
-
if (inFlight.current) return;
|
|
215
|
-
inFlight.current = true;
|
|
216
|
-
setSubmitting(true);
|
|
217
|
-
const from = opening.current;
|
|
218
|
-
let result: R;
|
|
219
|
-
try {
|
|
220
|
-
const [screenshot_url, attachment_urls] = await Promise.all([
|
|
221
|
-
data.screenshot ? upload(data.screenshot) : Promise.resolve(null),
|
|
222
|
-
Promise.all(data.attachments.map((file) => upload(file))),
|
|
223
|
-
]);
|
|
224
|
-
result = await create({
|
|
225
|
-
title: data.title.trim(),
|
|
226
|
-
body: data.body.trim() ? data.body : "",
|
|
227
|
-
category: data.category,
|
|
228
|
-
context,
|
|
229
|
-
screenshot_url,
|
|
230
|
-
attachment_urls,
|
|
231
|
-
});
|
|
232
|
-
} catch (error) {
|
|
233
|
-
toast.error(errorMessage ? errorMessage(error, toastText.submitFailed) : toastText.submitFailed);
|
|
234
|
-
return;
|
|
235
|
-
} finally {
|
|
236
|
-
inFlight.current = false;
|
|
237
|
-
setSubmitting(false);
|
|
238
|
-
}
|
|
239
|
-
toast.success(toastText.submitted);
|
|
240
|
-
if (opening.current === from) setIsOpen(false);
|
|
241
|
-
onSubmitted?.(result);
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// Nothing is drawn while the dialog's module is on its way — a few milliseconds, once per
|
|
245
|
-
// page load; a spinner would only flash. A load that fails (a deploy replaced the chunk,
|
|
246
|
-
// offline) closes the dialog (`SubmitDialogUnavailable`): the hook sits in the top bar,
|
|
247
|
-
// above the routes' error boundaries, where a thrown chunk error took the shell down.
|
|
248
|
-
const dialog = isOpen ? (
|
|
249
|
-
<Suspense fallback={null}>
|
|
250
|
-
<LazySubmitDialog
|
|
251
|
-
onClose={close}
|
|
252
|
-
category={category}
|
|
253
|
-
onCategoryChange={setCategory}
|
|
254
|
-
submitting={submitting}
|
|
255
|
-
onSubmit={submit}
|
|
256
|
-
user={user}
|
|
257
|
-
url={url}
|
|
258
|
-
attachUrl={attachUrl}
|
|
259
|
-
onAttachUrlChange={setAttachUrl}
|
|
260
|
-
environment={environment}
|
|
261
|
-
version={version}
|
|
262
|
-
capture={capture}
|
|
263
|
-
publicNotice={publicNotice}
|
|
264
|
-
opened={opened}
|
|
265
|
-
/>
|
|
266
|
-
</Suspense>
|
|
267
|
-
) : null;
|
|
268
|
-
|
|
269
|
-
return { open, close, dialog };
|
|
270
|
-
}
|