@eifi1/ui-kit 0.52.0 → 0.54.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 +52 -59
- package/dist/account/delete-account-setting.d.ts +3 -2
- package/dist/account/delete-account-setting.js.map +1 -1
- package/dist/auth/auth-errors.d.ts +36 -0
- package/dist/auth/auth-errors.js +20 -0
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/billing/cancel-subscription.d.ts +5 -14
- package/dist/billing/cancel-subscription.js +1 -3
- package/dist/billing/cancel-subscription.js.map +1 -1
- package/dist/billing/plan-card.d.ts +5 -13
- package/dist/billing/plan-card.js +3 -11
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/billing/plan-switch.d.ts +5 -14
- package/dist/billing/plan-switch.js +1 -3
- package/dist/billing/plan-switch.js.map +1 -1
- package/dist/chart.d.ts +3 -14
- package/dist/chart.js +64 -11
- package/dist/chart.js.map +1 -1
- package/dist/components/amount-input.d.ts +2 -1
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/calendar-heatmap.js +4 -2
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/currency-option-list.d.ts +2 -1
- package/dist/components/currency-option-list.js +10 -3
- package/dist/components/currency-option-list.js.map +1 -1
- package/dist/components/currency-select.d.ts +3 -1
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.d.ts +22 -1
- package/dist/components/danger-confirm.js +50 -28
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-filter-popover.d.ts +2 -1
- package/dist/components/data-table-filter-popover.js +3 -2
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +33 -3
- package/dist/components/data-table-filters.js +6 -4
- package/dist/components/data-table-filters.js.map +1 -1
- package/dist/components/date-field.d.ts +1 -1
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.d.ts +1 -1
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.d.ts +4 -17
- package/dist/components/date-range-picker.js +2 -2
- 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 +6 -2
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/mini-calendar.js +3 -2
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +27 -0
- package/dist/components/modal.js +5 -3
- package/dist/components/modal.js.map +1 -1
- package/dist/components/nav-pills.d.ts +1 -1
- package/dist/components/nav-pills.js.map +1 -1
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/series-chart-axes.d.ts +1 -1
- package/dist/components/series-chart-axes.js.map +1 -1
- package/dist/components/series-chart.d.ts +64 -19
- package/dist/components/series-chart.js +2 -1
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/stat-tile.d.ts +21 -2
- package/dist/components/stat-tile.js +4 -2
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/treemap-labels.d.ts +6 -1
- package/dist/components/treemap-labels.js +2 -2
- package/dist/components/treemap-labels.js.map +1 -1
- package/dist/components/treemap.d.ts +29 -4
- package/dist/components/treemap.js +22 -9
- package/dist/components/treemap.js.map +1 -1
- package/dist/currencies.d.ts +16 -2
- package/dist/currencies.js +2 -1
- package/dist/currencies.js.map +1 -1
- package/dist/data-table.d.ts +1 -6
- package/dist/data-table.js +1 -9
- package/dist/data-table.js.map +1 -1
- package/dist/demo/demo-countdown.d.ts +0 -5
- package/dist/demo/demo-countdown.js +0 -4
- package/dist/demo/demo-countdown.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/feedback/feedback-context-labels.js +2 -1
- package/dist/feedback/feedback-context-labels.js.map +1 -1
- package/dist/feedback/feedback-context.d.ts +19 -3
- package/dist/feedback/feedback-context.js +12 -1
- package/dist/feedback/feedback-context.js.map +1 -1
- package/dist/feedback/feedback-diagnostics.d.ts +17 -0
- package/dist/feedback/feedback-diagnostics.js +27 -0
- package/dist/feedback/feedback-diagnostics.js.map +1 -0
- package/dist/feedback/feedback-dialog.d.ts +10 -0
- package/dist/feedback/feedback-dialog.js +6 -4
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-mutation.d.ts +11 -23
- package/dist/feedback/feedback-mutation.js +1 -9
- package/dist/feedback/feedback-mutation.js.map +1 -1
- package/dist/feedback/feedback-public-list.d.ts +1 -6
- package/dist/feedback/feedback-public-list.js +1 -2
- package/dist/feedback/feedback-public-list.js.map +1 -1
- package/dist/feedback/feedback-record.d.ts +5 -0
- package/dist/feedback/feedback-record.js.map +1 -1
- package/dist/feedback/feedback-row-detail-labels.js +1 -8
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +6 -50
- package/dist/feedback/feedback-row-detail.js +3 -8
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +3 -19
- package/dist/feedback/feedback-status-undo.js.map +1 -1
- package/dist/feedback/feedback-submit-dialog.d.ts +5 -1
- package/dist/feedback/feedback-submit-dialog.js +15 -3
- package/dist/feedback/feedback-submit-dialog.js.map +1 -1
- package/dist/feedback/feedback-submit.d.ts +30 -2
- package/dist/feedback/feedback-submit.js +5 -2
- package/dist/feedback/feedback-submit.js.map +1 -1
- package/dist/feedback/feedback-thread.d.ts +0 -9
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +6 -40
- package/dist/feedback.js +88 -46
- package/dist/feedback.js.map +1 -1
- package/dist/hooks/use-hotkey.js +11 -1
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/i18n/defaults.js +0 -4
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +5 -20
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +5 -14
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +5 -31
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +5 -20
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +5 -20
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +5 -20
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +5 -21
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +5 -20
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +9 -4
- package/dist/i18n/review.js.map +1 -1
- package/dist/i18n/shared-labels.js +0 -1
- package/dist/i18n/shared-labels.js.map +1 -1
- package/dist/index.d.ts +18 -67
- package/dist/index.js +28 -103
- package/dist/index.js.map +1 -1
- package/dist/lib/dates.d.ts +7 -1
- package/dist/lib/dates.js +8 -1
- package/dist/lib/dates.js.map +1 -1
- package/dist/lib/format.d.ts +37 -2
- package/dist/lib/format.js +25 -1
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/intl-cache.d.ts +4 -2
- package/dist/lib/intl-cache.js.map +1 -1
- package/dist/lib/translation-review.d.ts +26 -0
- package/dist/lib/translation-review.js +14 -0
- package/dist/lib/translation-review.js.map +1 -1
- package/dist/rhf/fields.d.ts +2 -2
- package/dist/rhf/fields.js.map +1 -1
- package/dist/search/search-index.d.ts +0 -6
- package/dist/search/search-index.js +0 -4
- package/dist/search/search-index.js.map +1 -1
- package/dist/search.d.ts +1 -8
- package/dist/search.js +2 -7
- package/dist/search.js.map +1 -1
- package/dist/shell/account-menu-language.d.ts +7 -21
- package/dist/shell/account-menu-language.js +1 -3
- package/dist/shell/account-menu-language.js.map +1 -1
- package/dist/shell/account-menu-text-size.d.ts +9 -23
- package/dist/shell/account-menu-text-size.js +2 -3
- package/dist/shell/account-menu-text-size.js.map +1 -1
- package/dist/shell/app-shell.d.ts +0 -10
- package/dist/shell/app-shell.js +1 -7
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/company-switcher.d.ts +1 -1
- package/dist/shell/company-switcher.js.map +1 -1
- package/dist/shell/dev-menu.d.ts +1 -1
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +1 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +7 -29
- package/dist/shell.js +12 -42
- package/dist/shell.js.map +1 -1
- package/dist/sync.d.ts +2 -6
- package/dist/sync.js +2 -15
- package/dist/sync.js.map +1 -1
- package/dist/theme/chart-palette.d.ts +0 -5
- package/dist/theme/chart-palette.js +0 -2
- package/dist/theme/chart-palette.js.map +1 -1
- package/package.json +1 -1
- package/src/account/delete-account-setting.tsx +3 -2
- package/src/auth/auth-errors.ts +69 -0
- package/src/billing/cancel-subscription.tsx +5 -16
- package/src/billing/plan-card.tsx +7 -24
- package/src/billing/plan-switch.tsx +5 -16
- package/src/chart.ts +62 -13
- package/src/components/amount-input.tsx +2 -1
- package/src/components/calendar-heatmap.tsx +8 -2
- package/src/components/currency-option-list.tsx +12 -4
- package/src/components/currency-select.tsx +3 -1
- package/src/components/danger-confirm.tsx +80 -27
- package/src/components/data-table-filter-popover.tsx +19 -11
- package/src/components/data-table-filters.ts +36 -8
- package/src/components/date-field.tsx +1 -1
- package/src/components/date-picker.tsx +0 -1
- package/src/components/date-range-picker.tsx +6 -22
- package/src/components/dialog-frame.tsx +12 -4
- package/src/components/mini-calendar.tsx +5 -2
- package/src/components/modal.tsx +36 -7
- package/src/components/nav-pills.tsx +1 -1
- package/src/components/number-input.tsx +4 -3
- package/src/components/series-chart-axes.ts +6 -1
- package/src/components/series-chart.tsx +78 -21
- package/src/components/stat-tile.tsx +32 -3
- package/src/components/treemap-labels.ts +11 -3
- package/src/components/treemap.tsx +65 -12
- package/src/currencies.ts +23 -3
- package/src/data-table.ts +1 -11
- package/src/demo/demo-countdown.ts +3 -8
- package/src/feedback/feedback-context-labels.ts +1 -0
- package/src/feedback/feedback-context.tsx +34 -2
- package/src/feedback/feedback-diagnostics.tsx +41 -0
- package/src/feedback/feedback-dialog.tsx +16 -4
- package/src/feedback/feedback-mutation.ts +12 -33
- package/src/feedback/feedback-public-list.tsx +1 -7
- package/src/feedback/feedback-record.ts +5 -0
- package/src/feedback/feedback-row-detail-labels.ts +1 -8
- package/src/feedback/feedback-row-detail.tsx +21 -58
- package/src/feedback/feedback-status-undo.ts +4 -18
- package/src/feedback/feedback-submit-dialog.tsx +15 -2
- package/src/feedback/feedback-submit.tsx +36 -3
- package/src/feedback/feedback-thread.tsx +0 -10
- package/src/feedback.ts +89 -48
- package/src/hooks/use-hotkey.ts +24 -1
- package/src/i18n/defaults.ts +0 -4
- package/src/i18n/german.ts +4 -19
- package/src/i18n/kit-labels.tsx +5 -14
- package/src/i18n/locales/es.ts +4 -19
- package/src/i18n/locales/fr.ts +4 -19
- package/src/i18n/locales/hu.ts +4 -19
- package/src/i18n/locales/it.ts +4 -20
- package/src/i18n/locales/zh.ts +4 -19
- package/src/i18n/review.ts +9 -4
- package/src/i18n/shared-labels.ts +0 -1
- package/src/index.ts +44 -114
- package/src/lib/dates.ts +24 -2
- package/src/lib/format.ts +66 -3
- package/src/lib/intl-cache.ts +4 -2
- package/src/lib/translation-review.ts +52 -0
- package/src/rhf/fields.tsx +2 -2
- package/src/search/search-index.ts +0 -15
- package/src/search.ts +8 -8
- package/src/shell/account-menu-language.tsx +7 -27
- package/src/shell/account-menu-text-size.tsx +13 -32
- package/src/shell/app-shell.tsx +0 -13
- package/src/shell/company-switcher.tsx +1 -1
- package/src/shell/dev-menu.tsx +1 -1
- package/src/shell/top-bar-parts-labels.ts +1 -1
- package/src/shell.ts +17 -44
- package/src/sync.ts +2 -15
- package/src/theme/chart-palette.ts +0 -2
- package/tokens.css +4 -4
- package/dist/billing/dialog-close.d.ts +0 -29
- package/dist/billing/dialog-close.js +0 -8
- package/dist/billing/dialog-close.js.map +0 -1
- package/dist/components/field-sync-labels.d.ts +0 -3
- package/dist/components/field-sync-labels.js +0 -12
- package/dist/components/field-sync-labels.js.map +0 -1
- package/dist/components/field-sync.d.ts +0 -186
- package/dist/components/field-sync.js +0 -269
- package/dist/components/field-sync.js.map +0 -1
- package/dist/components/section-nav.d.ts +0 -44
- package/dist/components/section-nav.js +0 -33
- package/dist/components/section-nav.js.map +0 -1
- package/dist/components/sign-chip-labels.d.ts +0 -3
- package/dist/components/sign-chip-labels.js +0 -11
- package/dist/components/sign-chip-labels.js.map +0 -1
- package/dist/components/sign-chip.d.ts +0 -77
- package/dist/components/sign-chip.js +0 -47
- package/dist/components/sign-chip.js.map +0 -1
- package/dist/lib/isin.d.ts +0 -38
- package/dist/lib/isin.js +0 -36
- package/dist/lib/isin.js.map +0 -1
- package/dist/shell/role-switcher.d.ts +0 -28
- package/dist/shell/role-switcher.js +0 -31
- package/dist/shell/role-switcher.js.map +0 -1
- package/src/billing/dialog-close.ts +0 -34
- package/src/components/field-sync-labels.ts +0 -14
- package/src/components/field-sync.tsx +0 -504
- package/src/components/section-nav.tsx +0 -72
- package/src/components/sign-chip-labels.ts +0 -13
- package/src/components/sign-chip.tsx +0 -133
- package/src/lib/isin.ts +0 -72
- package/src/shell/role-switcher.tsx +0 -53
|
@@ -35,7 +35,8 @@ import {
|
|
|
35
35
|
splitDescription,
|
|
36
36
|
} from "./feedback-record";
|
|
37
37
|
import type { FeedbackContext, FeedbackRecord } from "./feedback-record";
|
|
38
|
-
import {
|
|
38
|
+
import { diagnosticsEntries, FeedbackDiagnosticsList } from "./feedback-diagnostics";
|
|
39
|
+
import { runMutation } from "./feedback-mutation";
|
|
39
40
|
import { feedbackPage, feedbackPageLinkTarget } from "./feedback-page-link";
|
|
40
41
|
import { useFeedbackStatusUndo } from "./feedback-status-undo";
|
|
41
42
|
import type { FeedbackStatusChange } from "./feedback-status-undo";
|
|
@@ -117,6 +118,9 @@ export interface FeedbackDetailLabels {
|
|
|
117
118
|
/** The copy button beside the link — copies the FULL `context.url`.
|
|
118
119
|
* de-CH: "URL kopieren" */
|
|
119
120
|
copyUrl: string;
|
|
121
|
+
/** The heading over `context.diagnostics`, between the URL and the attachment (keksdose
|
|
122
|
+
* live #481). de-CH: "Diagnose" */
|
|
123
|
+
diagnostics: string;
|
|
120
124
|
/** Section 3's heading, and each picture's alt text. de-CH: "Anhang" */
|
|
121
125
|
attachment: string;
|
|
122
126
|
/** A PDF's / text file's download button, given the file's name.
|
|
@@ -133,22 +137,6 @@ export interface FeedbackDetailLabels {
|
|
|
133
137
|
/** On section 4's heading line once the row is settled, given the formatted
|
|
134
138
|
* `resolved_at` date. de-CH: "Erledigt am: {{date}}" */
|
|
135
139
|
resolvedAt: (date: string) => string;
|
|
136
|
-
// Deprecated on these members, the ones an app's code reads and overrides through: the
|
|
137
|
-
// tags sat on the English default's keys, and reached nothing — the default is typed by
|
|
138
|
-
// this interface (0.52 code review, feedback-row-detail-labels.ts; refactor audit
|
|
139
|
-
// 2026-10-30, DOC-9).
|
|
140
|
-
/** The admin's button while there is no outcome — read by nothing since 0.38 (the
|
|
141
|
-
* outcome is frozen, §9.7; a reply is written instead). de-CH: "Ergebnis hinzufügen"
|
|
142
|
-
* @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
|
|
143
|
-
outcomeAdd: string;
|
|
144
|
-
/** The same button once there is one. Unused since 0.38, as `outcomeAdd`.
|
|
145
|
-
* de-CH: "Aktualisieren"
|
|
146
|
-
* @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
|
|
147
|
-
outcomeUpdate: string;
|
|
148
|
-
/** The line above the outcome editor. Unused since 0.38, as `outcomeAdd`.
|
|
149
|
-
* de-CH: "Was wurde umgesetzt, entschieden oder warum nicht."
|
|
150
|
-
* @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
|
|
151
|
-
outcomePlaceholder: string;
|
|
152
140
|
/** The button that opens section 5 on an answered row. de-CH: "Nacharbeit" */
|
|
153
141
|
rework: string;
|
|
154
142
|
/** Section 5's heading. de-CH: "Zur Nacharbeit senden" */
|
|
@@ -181,23 +169,10 @@ export function useFeedbackDetailLabels(labels?: LabelOverride<FeedbackDetailLab
|
|
|
181
169
|
|
|
182
170
|
/* ── The page a report was filed on (§3.2, §4.4.2) ────────────────────────── */
|
|
183
171
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
* page.
|
|
189
|
-
*
|
|
190
|
-
* Always a path on THIS app, never another origin's address — but the path and query
|
|
191
|
-
* are the reporter's to write, so it is TEXT, not a link target: `/join?token=…` acts on
|
|
192
|
-
* load, and `/login?next=…` forwards a signed-in admin to whatever its query names
|
|
193
|
-
* (refactor audit 2026-10-30, FLW-7; 0.52 code review). The kit's URL cell and section
|
|
194
|
-
* link {@link feedbackPagePath} alone, and not even that for a one-shot route
|
|
195
|
-
* (`pageLinkExclude`) — `FeedbackRowDetail` and `useFeedbackColumns` draw the page that
|
|
196
|
-
* way; an app's own cell should not link this.
|
|
197
|
-
*/
|
|
198
|
-
export function feedbackPageHref(context: FeedbackContext | null | undefined): string | null {
|
|
199
|
-
return feedbackPage(context)?.href ?? null;
|
|
200
|
-
}
|
|
172
|
+
// The page as the reporter had it (path + query + hash) and the full URL "Copy URL"
|
|
173
|
+
// copies were public too, as `feedbackPageHref` and `feedbackPageUrl`, until 0.53 (deprecated
|
|
174
|
+
// in 0.52, API-4): `feedbackPage` (./feedback-page-link) is the one reading, and the kit
|
|
175
|
+
// links only its path.
|
|
201
176
|
|
|
202
177
|
/** The page's path alone — the compact text a URL column shows (§4.3), and the only part
|
|
203
178
|
* of the page the kit links. */
|
|
@@ -205,15 +180,6 @@ export function feedbackPagePath(context: FeedbackContext | null | undefined): s
|
|
|
205
180
|
return feedbackPage(context)?.path ?? null;
|
|
206
181
|
}
|
|
207
182
|
|
|
208
|
-
/**
|
|
209
|
-
* What "Copy URL" copies: the FULL `context.url` as the reporter's browser had it —
|
|
210
|
-
* origin included, which is the one part that says which copy of the app it was
|
|
211
|
-
* (feedback #278) — else `context.route`. `null` when there is no page.
|
|
212
|
-
*/
|
|
213
|
-
export function feedbackPageUrl(context: FeedbackContext | null | undefined): string | null {
|
|
214
|
-
return feedbackPage(context)?.url ?? null;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
183
|
/* ── Attachments (§3.5, §4.4.3) ───────────────────────────────────────────── */
|
|
218
184
|
|
|
219
185
|
/**
|
|
@@ -319,17 +285,6 @@ export interface FeedbackDetailPatch {
|
|
|
319
285
|
*/
|
|
320
286
|
export type FeedbackDetailUpdateAsync = (patch: FeedbackDetailPatch) => Promise<unknown>;
|
|
321
287
|
|
|
322
|
-
/**
|
|
323
|
-
* The callback form: TanStack Query's `mutate`, or a function that calls `onSuccess` once
|
|
324
|
-
* the PATCH has landed. TanStack calls a per-call `onSuccess` for the LATEST `mutate()`
|
|
325
|
-
* only, so an editor whose save was followed by another PATCH before it answered stayed
|
|
326
|
-
* open, and the earlier status change lost its Undo.
|
|
327
|
-
*
|
|
328
|
-
* @deprecated 0.52 — pass `update.mutateAsync` ({@link FeedbackDetailUpdateAsync}); removed
|
|
329
|
-
* in 0.53
|
|
330
|
-
*/
|
|
331
|
-
export type FeedbackDetailUpdate = (patch: FeedbackDetailPatch, callbacks: { onSuccess: () => void }) => void;
|
|
332
|
-
|
|
333
288
|
/** `POST /feedback/attachments` (§3.3): one file up, its URL
|
|
334
289
|
* (`/api/v1/feedback/attachments/<key>`) back. Reject on failure. */
|
|
335
290
|
export type FeedbackUpload = (file: File) => Promise<string>;
|
|
@@ -351,7 +306,7 @@ export interface FeedbackReworkSectionProps {
|
|
|
351
306
|
/** The PATCH — see {@link FeedbackDetailUpdateAsync}. Called with `{ id, body }` only,
|
|
352
307
|
* and only without `onRework`: the legacy append (§3.4), which server-kit 0.13 still
|
|
353
308
|
* turns into an entry for one release. Optional since 0.40; pass one of the two. */
|
|
354
|
-
onUpdate?:
|
|
309
|
+
onUpdate?: FeedbackDetailUpdateAsync;
|
|
355
310
|
/** The PATCH is in flight (`update.isPending`). The upload adds its own. */
|
|
356
311
|
pending?: boolean;
|
|
357
312
|
/** The upload. Left out, the note goes without a file field. */
|
|
@@ -517,9 +472,8 @@ export interface FeedbackRowDetailProps {
|
|
|
517
472
|
/** The signed-in user's id — who the AUTHOR is: the description editor and rework. */
|
|
518
473
|
viewerId?: number | null;
|
|
519
474
|
/** The page's PATCH — `update.mutateAsync` (see {@link FeedbackDetailUpdateAsync}). The
|
|
520
|
-
* callback form
|
|
521
|
-
|
|
522
|
-
onUpdate: FeedbackMutationCall<FeedbackDetailPatch>;
|
|
475
|
+
* callback form, `update.mutate`, went in 0.53 (deprecated in 0.52). */
|
|
476
|
+
onUpdate: FeedbackDetailUpdateAsync;
|
|
523
477
|
/** `update.isPending`: the editors' save buttons wait for it. */
|
|
524
478
|
pending?: boolean;
|
|
525
479
|
/** `POST /feedback/attachments` for the rework's one file and, since 0.47 (§12) with
|
|
@@ -681,6 +635,9 @@ export function FeedbackRowDetail({
|
|
|
681
635
|
const { description } = splitDescription(row.body);
|
|
682
636
|
const page = feedbackPage(row.context);
|
|
683
637
|
const pageLink = page && feedbackPageLinkTarget(page, pageLinkExclude);
|
|
638
|
+
// What the app attached is for whoever handles the report and whoever sent it, never
|
|
639
|
+
// for another viewer of a shared row (keksdose live #481).
|
|
640
|
+
const diagnostics = canEdit || access.isAuthor ? diagnosticsEntries(row.context?.diagnostics) : [];
|
|
684
641
|
// 0.47 (§12): with the entries, each entry's file is drawn inline in the Replies
|
|
685
642
|
// timeline, so the Attachment section holds the report's own files.
|
|
686
643
|
const files = feedbackAttachmentUrls(row.replies ? { ...row, replies: undefined } : row);
|
|
@@ -783,6 +740,12 @@ export function FeedbackRowDetail({
|
|
|
783
740
|
</FeedbackDetailSection>
|
|
784
741
|
)}
|
|
785
742
|
|
|
743
|
+
{diagnostics.length > 0 && (
|
|
744
|
+
<FeedbackDetailSection title={labels.diagnostics}>
|
|
745
|
+
<FeedbackDiagnosticsList entries={diagnostics} />
|
|
746
|
+
</FeedbackDetailSection>
|
|
747
|
+
)}
|
|
748
|
+
|
|
786
749
|
{files.length > 0 && (
|
|
787
750
|
<FeedbackDetailSection title={labels.attachment}>
|
|
788
751
|
<div className="flex min-w-0 flex-wrap items-start gap-2">
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "./feedback-labels";
|
|
10
10
|
import type { FeedbackRecord } from "./feedback-record";
|
|
11
11
|
import type { LabelOverride } from "../i18n/kit-labels";
|
|
12
|
-
import { runMutation
|
|
12
|
+
import { runMutation } from "./feedback-mutation";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* A status change that can be taken back — §4.5 of the feedback contract, lifted from
|
|
@@ -42,17 +42,6 @@ export interface FeedbackStatusPatch {
|
|
|
42
42
|
*/
|
|
43
43
|
export type FeedbackStatusMutateAsync = (patch: FeedbackStatusPatch) => Promise<unknown>;
|
|
44
44
|
|
|
45
|
-
/**
|
|
46
|
-
* The callback form: TanStack Query's `mutate`, or a function that calls `onSuccess` once
|
|
47
|
-
* the PATCH has landed. TanStack calls a per-call `onSuccess` for the LATEST `mutate()` on
|
|
48
|
-
* its observer only, so a second change sent before the first answered — another swipe,
|
|
49
|
-
* another pill, the Undo itself — lost the first change's Undo toast.
|
|
50
|
-
*
|
|
51
|
-
* @deprecated 0.52 — pass `update.mutateAsync` ({@link FeedbackStatusMutateAsync}), whose
|
|
52
|
-
* promise settles for every call; removed in 0.53
|
|
53
|
-
*/
|
|
54
|
-
export type FeedbackStatusMutate = (patch: FeedbackStatusPatch, callbacks: { onSuccess: () => void }) => void;
|
|
55
|
-
|
|
56
45
|
/** What the change needs to know about the row: which one, what it is called in the
|
|
57
46
|
* toast, and where it stood (the status Undo goes back to). */
|
|
58
47
|
export type FeedbackStatusRow = Pick<FeedbackRecord, "id" | "title" | "status">;
|
|
@@ -90,14 +79,11 @@ export const FEEDBACK_UNDO_DURATION = 8000;
|
|
|
90
79
|
* `{ id, status: previous }` → once that has landed `statusRestored(previousName, title)`.
|
|
91
80
|
* Each change waits for its OWN answer, so two changes in flight each get their toast.
|
|
92
81
|
*
|
|
93
|
-
* `update.mutate
|
|
94
|
-
*
|
|
95
|
-
* takes both rather than two overloads: TypeScript types an inline callback's parameters
|
|
96
|
-
* from the FIRST overload, so a hand-written `(patch, { onSuccess }) => …` — the form this
|
|
97
|
-
* hook documented until 0.52 — would no longer compile.
|
|
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.
|
|
98
84
|
*/
|
|
99
85
|
export function useFeedbackStatusUndo(
|
|
100
|
-
mutate:
|
|
86
|
+
mutate: FeedbackStatusMutateAsync,
|
|
101
87
|
{ labels, statusLabels }: FeedbackStatusUndoOptions = {},
|
|
102
88
|
): FeedbackStatusChange {
|
|
103
89
|
const words = useFeedbackToastLabels(labels);
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type FeedbackContext,
|
|
13
13
|
type FeedbackEnvironment,
|
|
14
14
|
} from "./feedback-record";
|
|
15
|
+
import type { FeedbackSubmitOpenOptions } from "./feedback-submit";
|
|
15
16
|
import type { FeedbackCategory } from "./feedback-vocabulary";
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -49,6 +50,9 @@ export interface FeedbackSubmitDialogProps {
|
|
|
49
50
|
capture?: false | (() => Promise<File | null>);
|
|
50
51
|
/** `UseFeedbackSubmitOptions.publicNotice` (0.38): the line under the body. */
|
|
51
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;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
/** `FeedbackDialog` as `useFeedbackSubmit` settles it — see the hook for what it settles. */
|
|
@@ -66,6 +70,7 @@ export function FeedbackSubmitDialog({
|
|
|
66
70
|
version,
|
|
67
71
|
capture,
|
|
68
72
|
publicNotice = false,
|
|
73
|
+
opened: { diagnostics, title, body } = {},
|
|
69
74
|
}: FeedbackSubmitDialogProps) {
|
|
70
75
|
const toastText = useFeedbackToastLabels();
|
|
71
76
|
const dialogText = useKitLabels("feedbackDialog", DEFAULT_FEEDBACK_DIALOG_LABELS);
|
|
@@ -108,10 +113,18 @@ export function FeedbackSubmitDialog({
|
|
|
108
113
|
}
|
|
109
114
|
onCaptureScreenshot={onCaptureScreenshot}
|
|
110
115
|
publicNotice={publicNotice ? (dialogText.publicNotice ?? DEFAULT_FEEDBACK_DIALOG_LABELS.publicNotice) : undefined}
|
|
116
|
+
defaultTitle={title}
|
|
117
|
+
defaultBody={body}
|
|
111
118
|
// The context is read off the very values the box below shows (§3.2).
|
|
112
|
-
onSubmit={(data) => onSubmit(data, feedbackContext({ user, attachUrl, url, environment, version }))}
|
|
119
|
+
onSubmit={(data) => onSubmit(data, feedbackContext({ user, attachUrl, url, environment, version, diagnostics }))}
|
|
113
120
|
contextSlot={
|
|
114
|
-
<FeedbackContextBox
|
|
121
|
+
<FeedbackContextBox
|
|
122
|
+
user={user}
|
|
123
|
+
url={url}
|
|
124
|
+
attachUrl={attachUrl}
|
|
125
|
+
onAttachUrlChange={onAttachUrlChange}
|
|
126
|
+
diagnostics={diagnostics}
|
|
127
|
+
/>
|
|
115
128
|
}
|
|
116
129
|
/>
|
|
117
130
|
);
|
|
@@ -97,14 +97,42 @@ export interface UseFeedbackSubmitOptions<R = unknown> {
|
|
|
97
97
|
publicNotice?: boolean;
|
|
98
98
|
}
|
|
99
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
|
+
|
|
100
124
|
export interface FeedbackSubmit {
|
|
101
125
|
/**
|
|
102
126
|
* Open the dialog on `category` — a `FeedbackMenu` row's (§4.2: "default category when
|
|
103
127
|
* opened from a row: that row's"). Without one, or with `CRASH` (never pickable), it
|
|
104
128
|
* opens on `OTHER`, the server's own default (§3.4). Each open starts a fresh form,
|
|
105
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.
|
|
106
134
|
*/
|
|
107
|
-
open: (category?: FeedbackCategory) => void;
|
|
135
|
+
open: (category?: FeedbackCategory, options?: FeedbackSubmitOpenOptions) => void;
|
|
108
136
|
/** Close it, as Cancel does. */
|
|
109
137
|
close: () => void;
|
|
110
138
|
/**
|
|
@@ -140,7 +168,8 @@ export interface FeedbackSubmit {
|
|
|
140
168
|
* - The pickable categories — Bug, Idea, Question, Other, in the kit's words. `CRASH` is
|
|
141
169
|
* filed by the error boundary and is never offered (keksdose feedback #160).
|
|
142
170
|
* - The context box, built from the same values as the `context` it sends
|
|
143
|
-
* ({@link FeedbackContextBox} / `feedbackContext`), the URL read when the dialog OPENS
|
|
171
|
+
* ({@link FeedbackContextBox} / `feedbackContext`), the URL read when the dialog OPENS,
|
|
172
|
+
* and the diagnostics `open` was handed then (0.54, keksdose live #481).
|
|
144
173
|
* - Upload every file, then create (keksdose `use-feedback-dialog.tsx:89`): the
|
|
145
174
|
* screenshot to `screenshot_url`, the rest to `attachment_urls`, all in parallel.
|
|
146
175
|
* - The toasts, from `feedbackToast`: filed, failed (the server's `detail` through
|
|
@@ -161,18 +190,21 @@ export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions
|
|
|
161
190
|
const [category, setCategory] = useState<FeedbackCategory>("OTHER");
|
|
162
191
|
const [url, setUrl] = useState("");
|
|
163
192
|
const [attachUrl, setAttachUrl] = useState(true);
|
|
193
|
+
const [opened, setOpened] = useState<FeedbackSubmitOpenOptions>({});
|
|
164
194
|
const [submitting, setSubmitting] = useState(false);
|
|
165
195
|
// Which opening a send belongs to — see "closed and opened again" above.
|
|
166
196
|
const opening = useRef(0);
|
|
167
197
|
const inFlight = useRef(false);
|
|
168
198
|
|
|
169
|
-
const open = (next?: FeedbackCategory) => {
|
|
199
|
+
const open = (next?: FeedbackCategory, given?: FeedbackSubmitOpenOptions) => {
|
|
170
200
|
opening.current += 1;
|
|
171
201
|
setCategory(next && FEEDBACK_PICKABLE_CATEGORIES.includes(next) ? next : "OTHER");
|
|
172
202
|
setUrl(typeof window === "undefined" ? "" : window.location.href);
|
|
173
203
|
// Fresh every time (Kurvenschmiede use-feedback-dialog.tsx:80): a reporter who left the
|
|
174
204
|
// page out of one idea is not saying the bug report after it is unrelated too.
|
|
175
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 } });
|
|
176
208
|
setIsOpen(true);
|
|
177
209
|
};
|
|
178
210
|
const close = () => setIsOpen(false);
|
|
@@ -229,6 +261,7 @@ export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions
|
|
|
229
261
|
version={version}
|
|
230
262
|
capture={capture}
|
|
231
263
|
publicNotice={publicNotice}
|
|
264
|
+
opened={opened}
|
|
232
265
|
/>
|
|
233
266
|
</Suspense>
|
|
234
267
|
) : null;
|
|
@@ -903,13 +903,3 @@ function dataAttributes(props: object): Record<string, unknown> {
|
|
|
903
903
|
for (const [key, value] of Object.entries(props)) if (key.startsWith("data-")) out[key] = value;
|
|
904
904
|
return out;
|
|
905
905
|
}
|
|
906
|
-
|
|
907
|
-
/** @deprecated 0.52 — {@link ChatComposerProps}, the same type; removed in 0.53 */
|
|
908
|
-
export type FeedbackComposerProps = ChatComposerProps;
|
|
909
|
-
/** @deprecated 0.52 — {@link ChatComposerHandle}, the same type; removed in 0.53 */
|
|
910
|
-
export type FeedbackComposerHandle = ChatComposerHandle;
|
|
911
|
-
/** @deprecated 0.52 — {@link ChatComposerLabels}, the same type (still the provider's
|
|
912
|
-
* `feedbackComposer` namespace); removed in 0.53 */
|
|
913
|
-
export type FeedbackComposerLabels = ChatComposerLabels;
|
|
914
|
-
/** @deprecated 0.52 — {@link ChatComposerSlotContext}, the same type; removed in 0.53 */
|
|
915
|
-
export type FeedbackComposerSlotContext = ChatComposerSlotContext;
|
package/src/feedback.ts
CHANGED
|
@@ -9,20 +9,103 @@ export * from "./feedback/feedback-inbox";
|
|
|
9
9
|
export * from "./feedback/feedback-thread";
|
|
10
10
|
// 0.27.0: the feedback harmonization (docs/feedback-harmonization.md) — one record,
|
|
11
11
|
// one menu, dialog, table, detail and crash reporter for keksdose, kastlan, Kurvenschmiede.
|
|
12
|
-
|
|
12
|
+
//
|
|
13
|
+
// Named, not `*`, for six of its modules: 0.53 took the slice's share of the 55 names no app
|
|
14
|
+
// reads off the surface (deprecated in 0.52, refactor audit 2026-10-30, API-4) —
|
|
15
|
+
// `feedbackAttachmentLine`, `FEEDBACK_UNDO_DURATION`, `FEEDBACK_SWIPE_ACTIONS`,
|
|
16
|
+
// `feedbackColumns`, `feedbackSubmitter`, `feedbackSubmitterEmail`, `feedbackEnvironment`,
|
|
17
|
+
// `feedbackPagePath`, `feedbackAttachmentUrls`, `feedbackRowAccess`, `useFeedbackDetailLabels`
|
|
18
|
+
// and `feedbackPublicSwitchAllowed`, which their modules keep for the kit's own use.
|
|
19
|
+
// `feedbackPageHref` and `feedbackPageUrl` went whole: nothing read them.
|
|
20
|
+
export {
|
|
21
|
+
DEFAULT_ATTACHMENT_ACCEPT,
|
|
22
|
+
DEFAULT_MAX_ATTACHMENT_BYTES,
|
|
23
|
+
DEFAULT_MAX_ATTACHMENTS,
|
|
24
|
+
FEEDBACK_ATTACHMENT_ACCEPT,
|
|
25
|
+
FEEDBACK_PICKABLE_CATEGORIES,
|
|
26
|
+
FEEDBACK_REWORKABLE_STATUSES,
|
|
27
|
+
FEEDBACK_QUEUE_STATUSES,
|
|
28
|
+
FEEDBACK_AUTHOR_EDITABLE_STATUSES,
|
|
29
|
+
FEEDBACK_AWAITING_STATUSES,
|
|
30
|
+
FEEDBACK_DECIDED_STATUSES,
|
|
31
|
+
FEEDBACK_COMMENT_MAX,
|
|
32
|
+
FEEDBACK_REPLY_MAX,
|
|
33
|
+
appendRework,
|
|
34
|
+
reworkCount,
|
|
35
|
+
feedbackReworkCount,
|
|
36
|
+
splitBodyAttachments,
|
|
37
|
+
splitDescription,
|
|
38
|
+
replaceDescription,
|
|
39
|
+
isImageAttachment,
|
|
40
|
+
attachmentName,
|
|
41
|
+
type FeedbackEnvironment,
|
|
42
|
+
type FeedbackContext,
|
|
43
|
+
type FeedbackRecord,
|
|
44
|
+
} from "./feedback/feedback-record";
|
|
13
45
|
export * from "./feedback/feedback-labels";
|
|
14
|
-
export
|
|
15
|
-
|
|
46
|
+
export {
|
|
47
|
+
useFeedbackStatusUndo,
|
|
48
|
+
type FeedbackStatusPatch,
|
|
49
|
+
type FeedbackStatusMutateAsync,
|
|
50
|
+
type FeedbackStatusRow,
|
|
51
|
+
type FeedbackStatusChange,
|
|
52
|
+
type FeedbackStatusUndoOptions,
|
|
53
|
+
} from "./feedback/feedback-status-undo";
|
|
54
|
+
export {
|
|
55
|
+
DEFAULT_FEEDBACK_SWIPE,
|
|
56
|
+
feedbackSwipePlan,
|
|
57
|
+
feedbackSwipeOmitShown,
|
|
58
|
+
type FeedbackSwipeAction,
|
|
59
|
+
type FeedbackSwipeBinding,
|
|
60
|
+
type FeedbackSwipeOptions,
|
|
61
|
+
} from "./feedback/feedback-swipe";
|
|
16
62
|
export * from "./feedback/feedback-menu";
|
|
17
63
|
export * from "./feedback/feedback-context";
|
|
18
64
|
export * from "./feedback/feedback-capture";
|
|
19
65
|
export * from "./feedback/feedback-submit";
|
|
20
|
-
export
|
|
21
|
-
|
|
66
|
+
export {
|
|
67
|
+
DEFAULT_FEEDBACK_PAGE_LABELS,
|
|
68
|
+
useFeedbackPageLabels,
|
|
69
|
+
isFeedbackAwaiting,
|
|
70
|
+
useFeedbackRenderDate,
|
|
71
|
+
FeedbackSubject,
|
|
72
|
+
useFeedbackColumns,
|
|
73
|
+
feedbackMobileGroupBy,
|
|
74
|
+
FeedbackMobileCard,
|
|
75
|
+
FeedbackAwaitingToggle,
|
|
76
|
+
FeedbackEmptyState,
|
|
77
|
+
type FeedbackPageLabels,
|
|
78
|
+
type FeedbackTableRow,
|
|
79
|
+
type FeedbackRenderDate,
|
|
80
|
+
type FeedbackSubjectProps,
|
|
81
|
+
type FeedbackColumnsOptions,
|
|
82
|
+
type UseFeedbackColumnsOptions,
|
|
83
|
+
type FeedbackMobileCardProps,
|
|
84
|
+
type FeedbackAwaitingToggleProps,
|
|
85
|
+
type FeedbackEmptyStateProps,
|
|
86
|
+
} from "./feedback/feedback-table";
|
|
87
|
+
export {
|
|
88
|
+
DEFAULT_FEEDBACK_DETAIL_LABELS,
|
|
89
|
+
FeedbackReworkSection,
|
|
90
|
+
FeedbackRowDetail,
|
|
91
|
+
type FeedbackDetailLabels,
|
|
92
|
+
type FeedbackRowAccess,
|
|
93
|
+
type FeedbackDetailPatch,
|
|
94
|
+
type FeedbackDetailUpdateAsync,
|
|
95
|
+
type FeedbackUpload,
|
|
96
|
+
type FeedbackReworkSend,
|
|
97
|
+
type FeedbackReworkSectionProps,
|
|
98
|
+
type FeedbackRowDetailProps,
|
|
99
|
+
} from "./feedback/feedback-row-detail";
|
|
22
100
|
export * from "./feedback/feedback-crash";
|
|
23
101
|
// 0.38.0: the public pages (§9.15) — the "Visible to others" switch, the list every user
|
|
24
102
|
// reads and one report opened.
|
|
25
|
-
export
|
|
103
|
+
export {
|
|
104
|
+
FeedbackPublicSwitch,
|
|
105
|
+
type FeedbackPublicSwitchRow,
|
|
106
|
+
type FeedbackPublicSwitchViewer,
|
|
107
|
+
type FeedbackPublicSwitchProps,
|
|
108
|
+
} from "./feedback/feedback-public-switch";
|
|
26
109
|
export * from "./feedback/feedback-public-list";
|
|
27
110
|
// 0.38.0: public feedback (docs/feedback-harmonization.md §9) — the shapes, the vote, the
|
|
28
111
|
// comment thread, the replies' timeline and composer.
|
|
@@ -31,45 +114,3 @@ export * from "./feedback/feedback-vote-button";
|
|
|
31
114
|
export * from "./feedback/feedback-comment-thread";
|
|
32
115
|
export * from "./feedback/feedback-replies";
|
|
33
116
|
export * from "./feedback/feedback-entry-file";
|
|
34
|
-
// 0.52: the slice's share of the 55 names no app reads (refactor audit 2026-10-30, API-4,
|
|
35
|
-
// decision 4), tagged on their specifiers as the barrel's are — the modules keep them.
|
|
36
|
-
export {
|
|
37
|
-
/** @deprecated 0.52 — `appendRework`, which writes the line (API-4); removed in 0.53 */
|
|
38
|
-
feedbackAttachmentLine,
|
|
39
|
-
} from "./feedback/feedback-record";
|
|
40
|
-
export {
|
|
41
|
-
/** @deprecated 0.52 — `useFeedbackStatusUndo`, which keeps its Undo that long (API-4); removed in 0.53 */
|
|
42
|
-
FEEDBACK_UNDO_DURATION,
|
|
43
|
-
} from "./feedback/feedback-status-undo";
|
|
44
|
-
export {
|
|
45
|
-
/** @deprecated 0.52 — `DEFAULT_FEEDBACK_SWIPE` and `feedbackSwipePlan`, which name the actions (API-4); removed in 0.53 */
|
|
46
|
-
FEEDBACK_SWIPE_ACTIONS,
|
|
47
|
-
} from "./feedback/feedback-swipe";
|
|
48
|
-
export {
|
|
49
|
-
/** @deprecated 0.52 — `useFeedbackColumns`, the same columns in the provider's words (API-4); removed in 0.53 */
|
|
50
|
-
feedbackColumns,
|
|
51
|
-
/** @deprecated 0.52 — `useFeedbackColumns`, whose submitter cell reads it (API-4); removed in 0.53 */
|
|
52
|
-
feedbackSubmitter,
|
|
53
|
-
/** @deprecated 0.52 — `useFeedbackColumns`, whose submitter cell reads it (API-4); removed in 0.53 */
|
|
54
|
-
feedbackSubmitterEmail,
|
|
55
|
-
/** @deprecated 0.52 — `useFeedbackColumns`, whose environment cell reads it (API-4); removed in 0.53 */
|
|
56
|
-
feedbackEnvironment,
|
|
57
|
-
} from "./feedback/feedback-table";
|
|
58
|
-
export {
|
|
59
|
-
/** @deprecated 0.52 — `FeedbackRowDetail`, which links the page itself (API-4); removed in 0.53 */
|
|
60
|
-
feedbackPageUrl,
|
|
61
|
-
/** @deprecated 0.52 — `FeedbackRowDetail` and the table's URL cell, which link only a page's path and keep one-shot pages as text (the 0.52 code review's guard, which an app has no helper for); removed in 0.53 */
|
|
62
|
-
feedbackPageHref,
|
|
63
|
-
/** @deprecated 0.52 — `FeedbackRowDetail` and the table's URL cell, which show the page themselves; removed in 0.53 */
|
|
64
|
-
feedbackPagePath,
|
|
65
|
-
/** @deprecated 0.52 — `FeedbackRowDetail`, which lists the attachments itself (API-4); removed in 0.53 */
|
|
66
|
-
feedbackAttachmentUrls,
|
|
67
|
-
/** @deprecated 0.52 — `FeedbackRowDetail`, which decides who may edit what (API-4); removed in 0.53 */
|
|
68
|
-
feedbackRowAccess,
|
|
69
|
-
/** @deprecated 0.52 — `FeedbackRowDetail`, which resolves its words itself (API-4); removed in 0.53 */
|
|
70
|
-
useFeedbackDetailLabels,
|
|
71
|
-
} from "./feedback/feedback-row-detail";
|
|
72
|
-
export {
|
|
73
|
-
/** @deprecated 0.52 — `FeedbackPublicSwitch`, which asks it (API-4); removed in 0.53 */
|
|
74
|
-
feedbackPublicSwitchAllowed,
|
|
75
|
-
} from "./feedback/feedback-public-switch";
|
package/src/hooks/use-hotkey.ts
CHANGED
|
@@ -119,10 +119,33 @@ export function matchesHotkey(e: KeyboardEvent, combo: ParsedHotkey): boolean {
|
|
|
119
119
|
return symbol && !combo.shift ? true : e.shiftKey === combo.shift;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Whether `el` is editable content — `isContentEditable`, read from the attributes where
|
|
124
|
+
* the engine has no such property (keksdose audit follow-up, 2026-11-01). jsdom is one:
|
|
125
|
+
* there a hotkey fired while typing in a contenteditable, so a test could not show the
|
|
126
|
+
* editor keeping its letters, and an engine without the property would do the same.
|
|
127
|
+
*
|
|
128
|
+
* The nearest element with a `contenteditable` that names a state decides: `""`,
|
|
129
|
+
* `"true"` and `"plaintext-only"` edit, `"false"` does not — a `false` island inside an
|
|
130
|
+
* editor is not typed in. Any other value is the attribute's invalid-value default,
|
|
131
|
+
* which inherits, so the search goes on to the next one up. Keywords are
|
|
132
|
+
* case-insensitive. None at all: editable only in a `designMode` document.
|
|
133
|
+
*/
|
|
134
|
+
function isEditableContent(el: HTMLElement): boolean {
|
|
135
|
+
const native = (el as { isContentEditable?: boolean }).isContentEditable;
|
|
136
|
+
if (native !== undefined) return native;
|
|
137
|
+
for (let at = el.closest("[contenteditable]"); at; at = at.parentElement?.closest("[contenteditable]") ?? null) {
|
|
138
|
+
const state = (at.getAttribute("contenteditable") ?? "").toLowerCase();
|
|
139
|
+
if (state === "" || state === "true" || state === "plaintext-only") return true;
|
|
140
|
+
if (state === "false") return false;
|
|
141
|
+
}
|
|
142
|
+
return el.ownerDocument.designMode === "on";
|
|
143
|
+
}
|
|
144
|
+
|
|
122
145
|
/** Is the focus somewhere that takes typed characters? */
|
|
123
146
|
function isTypingTarget(target: EventTarget | null): boolean {
|
|
124
147
|
if (!(target instanceof HTMLElement)) return false;
|
|
125
|
-
if (target
|
|
148
|
+
if (isEditableContent(target)) return true;
|
|
126
149
|
if (target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement) return true;
|
|
127
150
|
if (target instanceof HTMLInputElement) {
|
|
128
151
|
return !["button", "checkbox", "radio", "submit", "reset", "range", "color", "file", "image"].includes(target.type);
|
package/src/i18n/defaults.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { DEFAULT_MONTH_PICKER_LABELS } from "../components/month-picker-labels";
|
|
|
5
5
|
import { DEFAULT_PAGE_CONTENTS_LABELS } from "../components/page-contents-labels";
|
|
6
6
|
import { DEFAULT_POPOVER_LABELS } from "../components/popover-labels";
|
|
7
7
|
import { DEFAULT_CHIP_INPUT_LABELS } from "../components/chip-labels";
|
|
8
|
-
import { DEFAULT_FIELD_SYNC_LABELS } from "../components/field-sync-labels";
|
|
9
8
|
import { DEFAULT_CHARACTER_COUNT_LABELS, DEFAULT_PASSWORD_REVEAL_LABELS } from "../components/field-base-labels";
|
|
10
9
|
import { DEFAULT_TABS_LABELS } from "../components/tabs-labels";
|
|
11
10
|
import { DEFAULT_WIZARD_LABELS } from "../wizard/wizard-labels";
|
|
@@ -109,7 +108,6 @@ import { DEFAULT_COUNTRY_SELECT_LABELS } from "../components/country-select-labe
|
|
|
109
108
|
import { DEFAULT_INLINE_EDIT_LABELS } from "../components/inline-edit-field-labels";
|
|
110
109
|
import { DEFAULT_IBAN_INPUT_LABELS } from "../components/iban-input-labels";
|
|
111
110
|
import { DEFAULT_PHONE_INPUT_LABELS } from "../components/phone-input-labels";
|
|
112
|
-
import { DEFAULT_SIGN_CHIP_LABELS } from "../components/sign-chip-labels";
|
|
113
111
|
import { DEFAULT_COLUMN_MAPPER_LABELS } from "../components/column-mapper-labels";
|
|
114
112
|
import { DEFAULT_NOTIFICATIONS_LABELS } from "../notifications/notifications-labels";
|
|
115
113
|
import {
|
|
@@ -157,7 +155,6 @@ export const DEFAULT_UI_KIT_LABELS: UiKitLabels = {
|
|
|
157
155
|
calculator: DEFAULT_CALCULATOR_LABELS,
|
|
158
156
|
currency: DEFAULT_CURRENCY_LABELS,
|
|
159
157
|
chipInput: DEFAULT_CHIP_INPUT_LABELS,
|
|
160
|
-
fieldSync: DEFAULT_FIELD_SYNC_LABELS,
|
|
161
158
|
passwordReveal: DEFAULT_PASSWORD_REVEAL_LABELS,
|
|
162
159
|
tabs: DEFAULT_TABS_LABELS,
|
|
163
160
|
appShell: DEFAULT_APP_SHELL_LABELS,
|
|
@@ -259,7 +256,6 @@ export const DEFAULT_UI_KIT_LABELS: UiKitLabels = {
|
|
|
259
256
|
inlineEdit: DEFAULT_INLINE_EDIT_LABELS,
|
|
260
257
|
ibanInput: DEFAULT_IBAN_INPUT_LABELS,
|
|
261
258
|
phoneInput: DEFAULT_PHONE_INPUT_LABELS,
|
|
262
|
-
signChip: DEFAULT_SIGN_CHIP_LABELS,
|
|
263
259
|
columnMapper: DEFAULT_COLUMN_MAPPER_LABELS,
|
|
264
260
|
notifications: DEFAULT_NOTIFICATIONS_LABELS,
|
|
265
261
|
adminArea: DEFAULT_ADMIN_AREA_LABELS,
|
package/src/i18n/german.ts
CHANGED
|
@@ -158,6 +158,7 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
158
158
|
feedbackContext: {
|
|
159
159
|
user: "Nutzer",
|
|
160
160
|
attachUrl: "Aktuelle Seiten-URL anhängen",
|
|
161
|
+
diagnostics: "Mitgesendete Diagnose",
|
|
161
162
|
},
|
|
162
163
|
feedbackPage: {
|
|
163
164
|
title: "Feedback-Eingang",
|
|
@@ -190,15 +191,13 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
190
191
|
cancel: "Abbrechen",
|
|
191
192
|
url: "URL",
|
|
192
193
|
copyUrl: "URL kopieren",
|
|
194
|
+
diagnostics: "Diagnose",
|
|
193
195
|
attachment: "Anhang",
|
|
194
196
|
download: (name) => `${name} herunterladen`,
|
|
195
197
|
downloadFailed: "Der Anhang konnte nicht heruntergeladen werden.",
|
|
196
198
|
outcome: "Ergebnis",
|
|
197
199
|
replies: "Antworten",
|
|
198
200
|
resolvedAt: (date) => `Erledigt am: ${date}`,
|
|
199
|
-
outcomeAdd: "Ergebnis hinzufügen",
|
|
200
|
-
outcomeUpdate: "Aktualisieren",
|
|
201
|
-
outcomePlaceholder: "Was wurde umgesetzt, entschieden oder warum nicht.",
|
|
202
201
|
rework: "Nacharbeit",
|
|
203
202
|
reworkTitle: "Zur Nacharbeit senden",
|
|
204
203
|
reworkSend: "Nacharbeit senden",
|
|
@@ -513,13 +512,6 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
513
512
|
noResults: "Keine passenden Symbole",
|
|
514
513
|
resultCount: (count) => `${n(count)} ${count === 1 ? "Symbol" : "Symbole"}`,
|
|
515
514
|
},
|
|
516
|
-
fieldSync: {
|
|
517
|
-
synced: "Gespeichert",
|
|
518
|
-
edited: "Nicht gespeicherte Änderungen",
|
|
519
|
-
pending: "Wird gespeichert…",
|
|
520
|
-
error: "Speichern fehlgeschlagen",
|
|
521
|
-
retry: "Erneut versuchen",
|
|
522
|
-
},
|
|
523
515
|
passwordReveal: {
|
|
524
516
|
show: "Passwort anzeigen",
|
|
525
517
|
hide: "Passwort verbergen",
|
|
@@ -553,7 +545,6 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
553
545
|
palette: "Darstellungsvorlage",
|
|
554
546
|
language: "Sprache",
|
|
555
547
|
languageCurrent: (name) => `Sprache wählen, aktuell: ${name}`,
|
|
556
|
-
switchRole: "Rolle wechseln",
|
|
557
548
|
role: (value) => `Rolle: ${value}`,
|
|
558
549
|
},
|
|
559
550
|
pickerSheet: {
|
|
@@ -755,8 +746,8 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
755
746
|
legend: "Kategorien",
|
|
756
747
|
},
|
|
757
748
|
treemap: {
|
|
758
|
-
tile: (name, value, share) => `${name}: ${value} (${share})`,
|
|
759
|
-
group: (name, value, share) => `${name}, Gruppe: ${value} (${share})`,
|
|
749
|
+
tile: (name, value, share) => `${name}: ${value}${share ? ` (${share})` : ""}`,
|
|
750
|
+
group: (name, value, share) => `${name}, Gruppe: ${value}${share ? ` (${share})` : ""}`,
|
|
760
751
|
inGroup: (name, group) => `${name}, in ${group}`,
|
|
761
752
|
},
|
|
762
753
|
confirmDialog: {
|
|
@@ -1569,12 +1560,6 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
1569
1560
|
countryCode: "Ländervorwahl",
|
|
1570
1561
|
other: "Andere",
|
|
1571
1562
|
},
|
|
1572
|
-
signChip: {
|
|
1573
|
-
outflow: "Ausgabe",
|
|
1574
|
-
inflow: "Einnahme",
|
|
1575
|
-
direction: (current, next) => `Richtung: ${current} – zu ${next} wechseln`,
|
|
1576
|
-
switchTo: (next) => `Zu ${next} wechseln`,
|
|
1577
|
-
},
|
|
1578
1563
|
columnMapper: {
|
|
1579
1564
|
paste: "Tabelle einfügen",
|
|
1580
1565
|
pasteHint:
|