@eifi1/ui-kit 0.38.0 → 0.39.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 +6 -5
- package/dist/auth/auth-errors.d.ts +8 -3
- package/dist/auth/auth-errors.js +3 -1
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/billing/billing-labels.d.ts +25 -2
- package/dist/billing/billing-labels.js +11 -2
- package/dist/billing/billing-labels.js.map +1 -1
- package/dist/billing/billing-overview.d.ts +50 -1
- package/dist/billing/checkout-processing.d.ts +15 -3
- package/dist/billing/checkout-processing.js +3 -1
- package/dist/billing/checkout-processing.js.map +1 -1
- package/dist/billing/pay-page.d.ts +55 -18
- package/dist/billing/pay-page.js +44 -10
- package/dist/billing/pay-page.js.map +1 -1
- package/dist/billing/plan-switch.d.ts +79 -0
- package/dist/billing/plan-switch.js +93 -0
- package/dist/billing/plan-switch.js.map +1 -0
- package/dist/bin/eifi1-pay-page.mjs +109 -21
- package/dist/eslint/index.js +1 -1
- package/dist/feedback/feedback-comment-thread.d.ts +13 -6
- package/dist/feedback/feedback-comment-thread.js +10 -2
- package/dist/feedback/feedback-comment-thread.js.map +1 -1
- package/dist/feedback/feedback-labels.d.ts +11 -0
- package/dist/feedback/feedback-labels.js +4 -1
- package/dist/feedback/feedback-labels.js.map +1 -1
- package/dist/feedback/feedback-public-labels.d.ts +3 -0
- package/dist/feedback/feedback-public-labels.js +2 -1
- package/dist/feedback/feedback-public-labels.js.map +1 -1
- package/dist/feedback/feedback-public-list.d.ts +25 -4
- package/dist/feedback/feedback-public-list.js +54 -3
- package/dist/feedback/feedback-public-list.js.map +1 -1
- package/dist/feedback/feedback-public-switch.js +3 -3
- package/dist/feedback/feedback-public-switch.js.map +1 -1
- package/dist/feedback/feedback-record.d.ts +7 -7
- package/dist/feedback/feedback-record.js.map +1 -1
- package/dist/feedback/feedback-replies-context.d.ts +7 -0
- package/dist/feedback/feedback-replies-context.js +7 -0
- package/dist/feedback/feedback-replies-context.js.map +1 -0
- package/dist/feedback/feedback-row-detail.d.ts +12 -3
- package/dist/feedback/feedback-row-detail.js +2 -1
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-table.js +2 -2
- package/dist/feedback/feedback-table.js.map +1 -1
- package/dist/feedback/feedback-vote-button.d.ts +2 -1
- package/dist/feedback/feedback-vote-button.js.map +1 -1
- package/dist/i18n/german.js +19 -4
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/locales/en.js +22 -6
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/es.js +19 -4
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +19 -4
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +19 -4
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +19 -4
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +19 -4
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +4 -0
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/translation-review.d.ts +11 -0
- package/dist/lib/translation-review.js.map +1 -1
- package/dist/pay/pay.js +102 -40
- package/package.json +1 -1
- package/src/auth/auth-errors.ts +12 -3
- package/src/billing/billing-labels.ts +38 -3
- package/src/billing/billing-overview.ts +53 -1
- package/src/billing/checkout-processing.ts +17 -3
- package/src/billing/pay-page.ts +111 -27
- package/src/billing/plan-switch.tsx +201 -0
- package/src/feedback/feedback-comment-thread.tsx +29 -7
- package/src/feedback/feedback-labels.ts +14 -0
- package/src/feedback/feedback-public-labels.ts +4 -0
- package/src/feedback/feedback-public-list.tsx +88 -5
- package/src/feedback/feedback-public-switch.tsx +3 -3
- package/src/feedback/feedback-record.ts +7 -7
- package/src/feedback/feedback-replies-context.ts +9 -0
- package/src/feedback/feedback-row-detail.tsx +16 -4
- package/src/feedback/feedback-table.tsx +2 -2
- package/src/feedback/feedback-vote-button.tsx +2 -1
- package/src/i18n/german.ts +17 -1
- package/src/i18n/locales/en.ts +1 -0
- package/src/i18n/locales/es.ts +16 -1
- package/src/i18n/locales/fr.ts +16 -2
- package/src/i18n/locales/hu.ts +16 -1
- package/src/i18n/locales/it.ts +16 -1
- package/src/i18n/locales/zh.ts +16 -1
- package/src/i18n/review.ts +4 -0
- package/src/index.ts +8 -0
- package/src/lib/translation-review.ts +12 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useMemo, useState } from "react";
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
|
-
import { MessageSquare, ThumbsUp } from "lucide-react";
|
|
3
|
+
import { ChevronLeft, ChevronRight, MessageSquare, ThumbsUp } from "lucide-react";
|
|
4
4
|
import { DataTable, type DataTableColumn } from "../components/data-table";
|
|
5
|
+
import { DEFAULT_DATA_TABLE_LABELS } from "../components/data-table-labels";
|
|
6
|
+
import { IconButton } from "../components/icon-button";
|
|
5
7
|
import { SearchField } from "../components/search-field";
|
|
6
8
|
import { ToggleGroup } from "../components/toggle-group";
|
|
7
9
|
import type { CommitScope } from "../components/write-lock";
|
|
@@ -80,6 +82,55 @@ function VoteCount({ count, voted, labels }: { count: number; voted: boolean; la
|
|
|
80
82
|
);
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
/** 0.38.1: previous / next over the server's pages when it answers no total
|
|
86
|
+
* (`GET /feedback/public` — Kurvenschmiede): "Page 3" between two arrows. The arrows'
|
|
87
|
+
* names are `dataTable`'s, the strip's; the page's is `feedbackPublic.page`. */
|
|
88
|
+
function PublicPager({
|
|
89
|
+
page,
|
|
90
|
+
hasMore,
|
|
91
|
+
onPageChange,
|
|
92
|
+
labels,
|
|
93
|
+
}: {
|
|
94
|
+
page: number;
|
|
95
|
+
hasMore: boolean;
|
|
96
|
+
onPageChange: (page: number) => void;
|
|
97
|
+
labels: FeedbackPublicLabels;
|
|
98
|
+
}) {
|
|
99
|
+
const tableLabels = useKitLabels("dataTable", DEFAULT_DATA_TABLE_LABELS);
|
|
100
|
+
const name = labels.page(page + 1);
|
|
101
|
+
return (
|
|
102
|
+
<div
|
|
103
|
+
role="group"
|
|
104
|
+
aria-label={name}
|
|
105
|
+
className="flex items-center justify-end gap-2 text-sm text-secondary"
|
|
106
|
+
data-feedback-public-pager={page}
|
|
107
|
+
>
|
|
108
|
+
<IconButton
|
|
109
|
+
size="sm"
|
|
110
|
+
variant="secondary"
|
|
111
|
+
label={tableLabels.prevPage}
|
|
112
|
+
disabled={page <= 0}
|
|
113
|
+
onClick={() => onPageChange(page - 1)}
|
|
114
|
+
>
|
|
115
|
+
{/* "Previous" points back along the line — left in LTR, right in RTL. */}
|
|
116
|
+
<ChevronLeft className="rtl:-scale-x-100" />
|
|
117
|
+
</IconButton>
|
|
118
|
+
<span className="tabular-nums" aria-hidden>
|
|
119
|
+
{name}
|
|
120
|
+
</span>
|
|
121
|
+
<IconButton
|
|
122
|
+
size="sm"
|
|
123
|
+
variant="secondary"
|
|
124
|
+
label={tableLabels.nextPage}
|
|
125
|
+
disabled={!hasMore}
|
|
126
|
+
onClick={() => onPageChange(page + 1)}
|
|
127
|
+
>
|
|
128
|
+
<ChevronRight className="rtl:-scale-x-100" />
|
|
129
|
+
</IconButton>
|
|
130
|
+
</div>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
83
134
|
/* ── The list ─────────────────────────────────────────────────────────────── */
|
|
84
135
|
|
|
85
136
|
export interface FeedbackPublicListProps<T extends FeedbackPublicListItem = FeedbackPublicListItem> {
|
|
@@ -110,6 +161,26 @@ export interface FeedbackPublicListProps<T extends FeedbackPublicListItem = Feed
|
|
|
110
161
|
* keeps it itself. */
|
|
111
162
|
openId?: number | null;
|
|
112
163
|
onOpenChange?: (id: number | null) => void;
|
|
164
|
+
/**
|
|
165
|
+
* 0.38.1: the opened report when it is NOT on this page — a `?row=` link to an older
|
|
166
|
+
* one (Kurvenschmiede). The app fetches it (`GET /feedback/public/{id}`, a list item's
|
|
167
|
+
* fields and more) and passes it with `openId`; while `openId` is its id it is drawn
|
|
168
|
+
* first, above the page's rows, and opened with `renderDetail` (on the phone, in the
|
|
169
|
+
* full-screen dialog). Closed, it is gone. A row the page has already is never drawn
|
|
170
|
+
* twice: the page's own is opened instead.
|
|
171
|
+
*/
|
|
172
|
+
openRow?: T | null;
|
|
173
|
+
/**
|
|
174
|
+
* 0.38.1: the server's page, from 0 — for a pager where `/feedback/public` answers no
|
|
175
|
+
* total (Kurvenschmiede). With {@link onPageChange} a **Previous / Page n / Next**
|
|
176
|
+
* strip stands under the table; Next is off without {@link hasMore}. Left out, no
|
|
177
|
+
* pager: the server's `limit` is all there is.
|
|
178
|
+
*/
|
|
179
|
+
page?: number;
|
|
180
|
+
/** 0.38.1: there is a page after this one (e.g. the page came back full). */
|
|
181
|
+
hasMore?: boolean;
|
|
182
|
+
/** 0.38.1: go to another page (`page ± 1`); the app fetches it. Draws the pager. */
|
|
183
|
+
onPageChange?: (page: number) => void;
|
|
113
184
|
/** A vote COMMITS — see Button's `commit`. */
|
|
114
185
|
commit?: CommitScope;
|
|
115
186
|
/** See {@link FeedbackRenderDate}. Default: the kit's, with the weekday. */
|
|
@@ -140,9 +211,10 @@ export interface FeedbackPublicListProps<T extends FeedbackPublicListItem = Feed
|
|
|
140
211
|
* counts; the vote itself is in the opened report (a button inside the card, which is
|
|
141
212
|
* the row's own button, would be two controls in one).
|
|
142
213
|
*
|
|
143
|
-
* No paging
|
|
144
|
-
*
|
|
145
|
-
*
|
|
214
|
+
* No client paging: the server's `limit` is the page, and `total` says how many there
|
|
215
|
+
* are. For more than one page, `page` / `hasMore` / `onPageChange` draw a previous /
|
|
216
|
+
* next strip that needs no total (0.38.1); `openRow` shows a `?row=` report from
|
|
217
|
+
* another page. Needs a router, as every `DataTable` does.
|
|
146
218
|
*/
|
|
147
219
|
export function FeedbackPublicList<T extends FeedbackPublicListItem = FeedbackPublicListItem>({
|
|
148
220
|
rows,
|
|
@@ -156,6 +228,10 @@ export function FeedbackPublicList<T extends FeedbackPublicListItem = FeedbackPu
|
|
|
156
228
|
loading = false,
|
|
157
229
|
openId: openIdProp,
|
|
158
230
|
onOpenChange,
|
|
231
|
+
openRow,
|
|
232
|
+
page: pageIndex = 0,
|
|
233
|
+
hasMore = false,
|
|
234
|
+
onPageChange,
|
|
159
235
|
commit,
|
|
160
236
|
renderDate: renderDateProp,
|
|
161
237
|
labels: labelsProp,
|
|
@@ -172,6 +248,10 @@ export function FeedbackPublicList<T extends FeedbackPublicListItem = FeedbackPu
|
|
|
172
248
|
if (openIdProp === undefined) setOwnOpenId(id);
|
|
173
249
|
onOpenChange?.(id);
|
|
174
250
|
};
|
|
251
|
+
// A `?row=` report from another page: first, while it is the open one, and only when
|
|
252
|
+
// the page does not have it itself.
|
|
253
|
+
const shownRows =
|
|
254
|
+
openRow && openId === openRow.id && !rows.some((row) => row.id === openRow.id) ? [openRow, ...rows] : rows;
|
|
175
255
|
|
|
176
256
|
const columns = useMemo<DataTableColumn<T>[]>(
|
|
177
257
|
() => [
|
|
@@ -257,7 +337,7 @@ export function FeedbackPublicList<T extends FeedbackPublicListItem = FeedbackPu
|
|
|
257
337
|
)}
|
|
258
338
|
</div>
|
|
259
339
|
<DataTable
|
|
260
|
-
rows={
|
|
340
|
+
rows={shownRows}
|
|
261
341
|
columns={columns}
|
|
262
342
|
rowKey={(row) => row.id}
|
|
263
343
|
rowName={(row) => row.title}
|
|
@@ -284,6 +364,9 @@ export function FeedbackPublicList<T extends FeedbackPublicListItem = FeedbackPu
|
|
|
284
364
|
</div>
|
|
285
365
|
)}
|
|
286
366
|
/>
|
|
367
|
+
{onPageChange && (pageIndex > 0 || hasMore) && (
|
|
368
|
+
<PublicPager page={pageIndex} hasMore={hasMore} onPageChange={onPageChange} labels={labels} />
|
|
369
|
+
)}
|
|
287
370
|
</div>
|
|
288
371
|
);
|
|
289
372
|
}
|
|
@@ -19,7 +19,7 @@ export interface FeedbackPublicSwitchViewer {
|
|
|
19
19
|
/** The viewer filed the row — `mine` when the server sent it, else the ids (never for an
|
|
20
20
|
* erased author, `user_id: null`). */
|
|
21
21
|
function isAuthorOf(row: FeedbackPublicSwitchRow, viewerId: number | null | undefined): boolean {
|
|
22
|
-
if (row.mine
|
|
22
|
+
if (row.mine != null) return row.mine;
|
|
23
23
|
return row.user_id !== null && viewerId !== undefined && viewerId !== null && row.user_id === viewerId;
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -83,7 +83,7 @@ export function FeedbackPublicSwitch({
|
|
|
83
83
|
className,
|
|
84
84
|
}: FeedbackPublicSwitchProps) {
|
|
85
85
|
const labels = useKitLabels("feedbackPublic", DEFAULT_FEEDBACK_PUBLIC_LABELS, labelsProp);
|
|
86
|
-
if (row.category === "CRASH" || row.public
|
|
86
|
+
if (row.category === "CRASH" || row.public == null) return null;
|
|
87
87
|
if (!isAdmin && !isAuthorOf(row, viewerId)) return null;
|
|
88
88
|
const allowed = feedbackPublicSwitchAllowed(row, { isAdmin, viewerId });
|
|
89
89
|
return (
|
|
@@ -91,7 +91,7 @@ export function FeedbackPublicSwitch({
|
|
|
91
91
|
className={className}
|
|
92
92
|
label={labels.visibleToOthers}
|
|
93
93
|
description={labels.visibleHint}
|
|
94
|
-
checked={row.public}
|
|
94
|
+
checked={row.public === true}
|
|
95
95
|
disabled={pending}
|
|
96
96
|
disabledReason={allowed ? undefined : labels.visibleLocked}
|
|
97
97
|
commit={commit}
|
|
@@ -117,20 +117,20 @@ export interface FeedbackRecord {
|
|
|
117
117
|
/** The admin: the full name; the author: their own; `null`: none to show. */
|
|
118
118
|
author_name?: string | null;
|
|
119
119
|
/** The viewer filed it. */
|
|
120
|
-
mine?: boolean;
|
|
120
|
+
mine?: boolean | null;
|
|
121
121
|
/** Visible to the app's other users (§9.3); never on a CRASH. */
|
|
122
|
-
public?: boolean;
|
|
122
|
+
public?: boolean | null;
|
|
123
123
|
/** Made public by the 0.38 migration: the author may switch it off at any status. */
|
|
124
|
-
filed_private?: boolean;
|
|
124
|
+
filed_private?: boolean | null;
|
|
125
125
|
/** People who want this (the author's own vote included, §9.6). */
|
|
126
|
-
votes?: number;
|
|
126
|
+
votes?: number | null;
|
|
127
127
|
/** The viewer's vote. */
|
|
128
|
-
voted?: boolean;
|
|
128
|
+
voted?: boolean | null;
|
|
129
129
|
/** Comments (an admin's count includes hidden ones). */
|
|
130
|
-
comment_count?: number;
|
|
130
|
+
comment_count?: number | null;
|
|
131
131
|
/** The admin's answers, oldest first (§9.7). Absent: a server before 0.38 — read
|
|
132
132
|
* `outcome` instead. */
|
|
133
|
-
replies?: FeedbackReply[];
|
|
133
|
+
replies?: FeedbackReply[] | null;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/* ── Constants (§3.4, §3.5, §4.3) ─────────────────────────────────────────── */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `true` inside `FeedbackRowDetail`'s Comments section (0.38.1, Kurvenschmiede): the
|
|
5
|
+
* detail's own Replies section draws the report's replies already, so a
|
|
6
|
+
* `FeedbackCommentThread` there draws the comments alone — whatever `replies` it was
|
|
7
|
+
* handed. Internal: not re-exported.
|
|
8
|
+
*/
|
|
9
|
+
export const FeedbackRepliesDrawnAboveContext = createContext(false);
|
|
@@ -42,6 +42,7 @@ import type { CommitScope } from "../components/write-lock";
|
|
|
42
42
|
import { DEFAULT_FEEDBACK_DETAIL_LABELS } from "./feedback-row-detail-labels";
|
|
43
43
|
import { FeedbackReplyComposer, FeedbackReplyTimeline, feedbackReplyNudge } from "./feedback-replies";
|
|
44
44
|
import { FeedbackPublicSwitch } from "./feedback-public-switch";
|
|
45
|
+
import { FeedbackRepliesDrawnAboveContext } from "./feedback-replies-context";
|
|
45
46
|
import { DEFAULT_FEEDBACK_COMMENTS_LABELS } from "./feedback-thread-parts-labels";
|
|
46
47
|
|
|
47
48
|
/**
|
|
@@ -373,6 +374,10 @@ export interface FeedbackDetailPatch {
|
|
|
373
374
|
* answers 422; the detail no longer sends it (a reply is written instead). */
|
|
374
375
|
outcome?: string | null;
|
|
375
376
|
status?: FeedbackStatus;
|
|
377
|
+
/** 0.38.1: the **Visible to others** flip (§9.3) — what `onPublicChange`'s
|
|
378
|
+
* `PATCH /feedback/{id} {"public": next}` carries, alone, so an app can send it
|
|
379
|
+
* through the same `onUpdate` mutation. */
|
|
380
|
+
public?: boolean;
|
|
376
381
|
}
|
|
377
382
|
|
|
378
383
|
/**
|
|
@@ -582,17 +587,22 @@ export interface FeedbackRowDetailProps {
|
|
|
582
587
|
* 0.38: `POST /feedback/{id}/replies` (§9.7) — the body and the status picked
|
|
583
588
|
* (`undefined`: "No change"). With `canEdit` and a row that carries `replies`, the
|
|
584
589
|
* reply composer stands under the timeline. Return the promise: the box clears when it
|
|
585
|
-
* resolves.
|
|
590
|
+
* resolves. A failure is the app's to toast — the server's `detail`, else
|
|
591
|
+
* `feedbackToast.replyFailed` (0.38.1).
|
|
586
592
|
*/
|
|
587
593
|
onReply?: (body: string, status?: FeedbackStatus) => void | Promise<unknown>;
|
|
588
594
|
/** 0.38: the reply is in flight. */
|
|
589
595
|
replying?: boolean;
|
|
590
596
|
/** 0.38: the report's comments — the app's `FeedbackCommentThread` — in a section of
|
|
591
|
-
* their own under the replies.
|
|
597
|
+
* their own under the replies. A thread here draws the comments alone (0.38.1): the
|
|
598
|
+
* Replies section above has the replies, so whatever `replies` the thread is handed
|
|
599
|
+
* are dropped, and nothing is drawn twice. */
|
|
592
600
|
comments?: ReactNode;
|
|
593
601
|
/** 0.38: `PATCH /feedback/{id} {"public": next}` — draws the **Visible to others**
|
|
594
602
|
* switch (`FeedbackPublicSwitch`) in the Status section, for the admin (`canEdit`)
|
|
595
|
-
* and, within §9.3's window, the author.
|
|
603
|
+
* and, within §9.3's window, the author. The page's own mutation fits:
|
|
604
|
+
* `onPublicChange={(next) => update.mutate({ id: row.id, public: next })}` —
|
|
605
|
+
* {@link FeedbackDetailPatch}'s `public` (0.38.1). */
|
|
596
606
|
onPublicChange?: (next: boolean) => void;
|
|
597
607
|
labels?: LabelOverride<FeedbackDetailLabels>;
|
|
598
608
|
className?: string;
|
|
@@ -818,7 +828,9 @@ export function FeedbackRowDetail({
|
|
|
818
828
|
</FeedbackDetailSection>
|
|
819
829
|
|
|
820
830
|
{comments != null && (
|
|
821
|
-
<FeedbackDetailSection title={commentLabels.comments}>
|
|
831
|
+
<FeedbackDetailSection title={commentLabels.comments}>
|
|
832
|
+
<FeedbackRepliesDrawnAboveContext.Provider value>{comments}</FeedbackRepliesDrawnAboveContext.Provider>
|
|
833
|
+
</FeedbackDetailSection>
|
|
822
834
|
)}
|
|
823
835
|
|
|
824
836
|
{showRework && (
|
|
@@ -472,7 +472,7 @@ export function feedbackColumns<T extends FeedbackTableRow>({
|
|
|
472
472
|
key: "votes",
|
|
473
473
|
header: votesHeader,
|
|
474
474
|
className: "whitespace-nowrap",
|
|
475
|
-
cell: (row) => <FeedbackVoteCount votes={row.votes} />,
|
|
475
|
+
cell: (row) => <FeedbackVoteCount votes={row.votes ?? undefined} />,
|
|
476
476
|
sortBy: (row) => row.votes ?? 0,
|
|
477
477
|
filter: { type: "number", getValue: (row) => row.votes ?? 0 },
|
|
478
478
|
mobileHidden: true,
|
|
@@ -710,7 +710,7 @@ export function FeedbackMobileCard({
|
|
|
710
710
|
</div>
|
|
711
711
|
<div className="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-muted">
|
|
712
712
|
<FeedbackCategoryBadge category={row.category} compact />
|
|
713
|
-
{votes && <FeedbackVoteCount votes={row.votes} />}
|
|
713
|
+
{votes && <FeedbackVoteCount votes={row.votes ?? undefined} />}
|
|
714
714
|
<FeedbackDate value={row.created_at} renderDate={renderDate} />
|
|
715
715
|
{showSubmitter && (
|
|
716
716
|
// The short id form: "#7" says enough on a card that has room for little.
|
|
@@ -19,7 +19,8 @@ import { DEFAULT_FEEDBACK_VOTE_LABELS } from "./feedback-thread-parts-labels";
|
|
|
19
19
|
* - **Optimistic with rollback:** the press shows the new state at once, `onVote(next)`
|
|
20
20
|
* sends `PUT` (`true`) or `DELETE` (`false`) and its answer — the server's count —
|
|
21
21
|
* replaces the guess; a rejection puts back what was there. The error is the app's
|
|
22
|
-
* to toast (its mutation's `onError`), as with every kit part that takes a promise
|
|
22
|
+
* to toast (its mutation's `onError`), as with every kit part that takes a promise —
|
|
23
|
+
* the server's `detail`, else `feedbackToast.voteFailed` (0.38.1).
|
|
23
24
|
* - **The author's own report** counts as their vote (§9.6, decision 20): `own` shows it
|
|
24
25
|
* pressed and `aria-disabled` with "Your report" as the reason (the server would
|
|
25
26
|
* answer 409).
|
package/src/i18n/german.ts
CHANGED
|
@@ -113,6 +113,9 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
113
113
|
statusChanged: (status, title) => `Auf „${status}“ gesetzt: ${title}`,
|
|
114
114
|
statusUndo: "Rückgängig",
|
|
115
115
|
statusRestored: (status, title) => `Zurück auf „${status}“: ${title}`,
|
|
116
|
+
commentFailed: "Kommentar konnte nicht gesendet werden.",
|
|
117
|
+
voteFailed: "Stimme konnte nicht gespeichert werden.",
|
|
118
|
+
replyFailed: "Antwort konnte nicht gesendet werden.",
|
|
116
119
|
},
|
|
117
120
|
feedbackMenu: {
|
|
118
121
|
trigger: "Feedback senden",
|
|
@@ -142,6 +145,7 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
142
145
|
visibleToOthers: "Für andere sichtbar",
|
|
143
146
|
visibleHint: "Andere Personen sehen Titel und Text, nie Ihre Screenshots oder Dateien.",
|
|
144
147
|
visibleLocked: "Nur solange die Meldung noch offen ist.",
|
|
148
|
+
page: (page) => `Seite ${n(page)}`,
|
|
145
149
|
},
|
|
146
150
|
feedbackNotificationTypes: {
|
|
147
151
|
answered: "Antworten auf Ihre Meldungen",
|
|
@@ -1745,6 +1749,14 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
1745
1749
|
"Der Bezahlvorgang konnte nicht geöffnet werden. Bitte kehren Sie zurück und versuchen Sie es gleich noch einmal.",
|
|
1746
1750
|
payBack:
|
|
1747
1751
|
"Der Bezahlvorgang wurde geschlossen. Sie können zurückkehren oder diese Seite neu laden, um ihn wieder zu öffnen.",
|
|
1752
|
+
payDone: "Zahlung abgeschlossen. Sie können diese Seite schließen.",
|
|
1753
|
+
// 0.39 (§15.2.10): PlanSwitchConfirm.
|
|
1754
|
+
switchTitle: "Tarif ändern",
|
|
1755
|
+
switchFromTo: (from, to) => `Von ${from} zu ${to}`,
|
|
1756
|
+
switchChargedNow: "Jetzt belastet",
|
|
1757
|
+
switchCredited: "Gutschrift auf die nächsten Belastungen",
|
|
1758
|
+
switchNextCharge: (date) => `Nächste Belastung am ${date}`,
|
|
1759
|
+
switchConfirm: "Tarif ändern",
|
|
1748
1760
|
waitingChanges: (count) =>
|
|
1749
1761
|
count === 1
|
|
1750
1762
|
? `${n(count)} Änderung wartet auf einen Tarif`
|
|
@@ -1756,9 +1768,13 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
1756
1768
|
// §14.2: server-kit 0.7's refusals. "Zahlung und Rechnungen", as `manage`.
|
|
1757
1769
|
providerUnavailable:
|
|
1758
1770
|
"Der Zahlungsanbieter ist gerade nicht erreichbar. Bitte versuchen Sie es gleich noch einmal.",
|
|
1759
|
-
alreadySubscribed: "Sie haben bereits ein Abonnement.
|
|
1771
|
+
alreadySubscribed: "Sie haben bereits ein Abonnement. Ändern Sie Ihren Tarif oben.",
|
|
1760
1772
|
planNotSold:
|
|
1761
1773
|
"Dieser Tarif ist für diesen Abrechnungszeitraum oder diese Währung nicht erhältlich. Bitte wählen Sie einen anderen.",
|
|
1774
|
+
// 0.39 (§15.2.10): the plan switch's refusals.
|
|
1775
|
+
notSubscribed:
|
|
1776
|
+
"Es läuft kein Abonnement, das sich ändern ließe. Wählen Sie einen Tarif, um eines abzuschließen.",
|
|
1777
|
+
planUnchanged: "Das ist bereits Ihr Tarif. Wählen Sie einen anderen Tarif oder Abrechnungszeitraum.",
|
|
1762
1778
|
},
|
|
1763
1779
|
// 0.33.0 — docs/billing-harmonization.md §14.12: the operator's plan parts, "Tarif" as
|
|
1764
1780
|
// in `billing`; keksdose's reviewed admin wording where it had one.
|
package/src/i18n/locales/en.ts
CHANGED
|
@@ -54,6 +54,7 @@ export function uiKitLabelsEn(numberLocale = "en-US"): UiKitLabels {
|
|
|
54
54
|
total: (count) => (count === 1 ? "1 report" : `${n(count)} reports`),
|
|
55
55
|
comments: (count) => (count === 1 ? "1 comment" : `${n(count)} comments`),
|
|
56
56
|
votes: (count) => (count === 1 ? "1 vote" : `${n(count)} votes`),
|
|
57
|
+
page: (page) => `Page ${n(page)}`,
|
|
57
58
|
},
|
|
58
59
|
measuredGrid: {
|
|
59
60
|
...d.measuredGrid,
|
package/src/i18n/locales/es.ts
CHANGED
|
@@ -104,6 +104,9 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
104
104
|
statusChanged: (status, title) => `Cambiado a «${status}»: ${title}`,
|
|
105
105
|
statusUndo: "Deshacer",
|
|
106
106
|
statusRestored: (status, title) => `De vuelta a «${status}»: ${title}`,
|
|
107
|
+
commentFailed: "No se ha podido publicar el comentario.",
|
|
108
|
+
voteFailed: "No se ha podido guardar su voto.",
|
|
109
|
+
replyFailed: "No se ha podido enviar la respuesta.",
|
|
107
110
|
},
|
|
108
111
|
feedbackMenu: {
|
|
109
112
|
trigger: "Enviar comentarios",
|
|
@@ -133,6 +136,7 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
133
136
|
visibleToOthers: "Visible para otras personas",
|
|
134
137
|
visibleHint: "Otras personas ven el título y el texto, nunca sus capturas ni sus archivos.",
|
|
135
138
|
visibleLocked: "Solo mientras el informe siga abierto.",
|
|
139
|
+
page: (page) => `Página ${n(page)}`,
|
|
136
140
|
},
|
|
137
141
|
feedbackNotificationTypes: {
|
|
138
142
|
answered: "Respuestas a sus informes",
|
|
@@ -1695,6 +1699,14 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
1695
1699
|
payNothing: "Aquí no hay nada que pagar. Para elegir un plan, vuelva a la aplicación.",
|
|
1696
1700
|
payFailed: "No se ha podido abrir el pago. Vuelva atrás e inténtelo de nuevo en un momento.",
|
|
1697
1701
|
payBack: "El pago se ha cerrado. Puede volver atrás o recargar esta página para abrirlo de nuevo.",
|
|
1702
|
+
payDone: "Pago completado. Puede cerrar esta página.",
|
|
1703
|
+
// 0.39 (§15.2.10): PlanSwitchConfirm.
|
|
1704
|
+
switchTitle: "Cambiar de plan",
|
|
1705
|
+
switchFromTo: (from, to) => `De ${from} a ${to}`,
|
|
1706
|
+
switchChargedNow: "Cargo ahora",
|
|
1707
|
+
switchCredited: "Abonado a sus próximos cargos",
|
|
1708
|
+
switchNextCharge: (date) => `Próximo cargo el ${date}`,
|
|
1709
|
+
switchConfirm: "Cambiar de plan",
|
|
1698
1710
|
waitingChanges: (count) => `${n(count)} ${plural(count, "cambio", "cambios")} a la espera de un plan`,
|
|
1699
1711
|
// "Descartar", as `wizard.cancelConfirmLabel`.
|
|
1700
1712
|
discardWaiting: "Descartar los cambios en espera",
|
|
@@ -1702,8 +1714,11 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
1702
1714
|
disabled: "Las suscripciones no están disponibles aquí.",
|
|
1703
1715
|
// §14.2: server-kit 0.7's refusals. "Pagos y facturas", as `manage`. "Usted".
|
|
1704
1716
|
providerUnavailable: "El proveedor de pagos no está disponible en este momento. Inténtelo de nuevo en un momento.",
|
|
1705
|
-
alreadySubscribed: "Ya tiene una suscripción.
|
|
1717
|
+
alreadySubscribed: "Ya tiene una suscripción. Cambie de plan más arriba.",
|
|
1706
1718
|
planNotSold: "Este plan no está disponible para ese periodo de facturación o esa moneda. Elija otro.",
|
|
1719
|
+
// 0.39 (§15.2.10): the plan switch's refusals.
|
|
1720
|
+
notSubscribed: "No hay ninguna suscripción activa que cambiar. Elija un plan para suscribirse.",
|
|
1721
|
+
planUnchanged: "Ese ya es su plan. Elija otro plan u otro periodo de facturación.",
|
|
1707
1722
|
},
|
|
1708
1723
|
// 0.33.0 — docs/billing-harmonization.md §14.12: the operator's plan parts, "plan" as
|
|
1709
1724
|
// in `billing`. "Usted".
|
package/src/i18n/locales/fr.ts
CHANGED
|
@@ -102,6 +102,9 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
102
102
|
statusChanged: (status, title) => `Passé à «\u202f${status}\u202f»\u00a0: ${title}`,
|
|
103
103
|
statusUndo: "Annuler",
|
|
104
104
|
statusRestored: (status, title) => `Revenu à «\u202f${status}\u202f»\u00a0: ${title}`,
|
|
105
|
+
commentFailed: "Le commentaire n’a pas pu être publié.",
|
|
106
|
+
voteFailed: "Votre vote n’a pas pu être enregistré.",
|
|
107
|
+
replyFailed: "La réponse n’a pas pu être envoyée.",
|
|
105
108
|
},
|
|
106
109
|
feedbackMenu: {
|
|
107
110
|
trigger: "Envoyer un retour",
|
|
@@ -131,6 +134,7 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
131
134
|
visibleToOthers: "Visible par les autres",
|
|
132
135
|
visibleHint: "Les autres personnes voient le titre et le texte, jamais vos captures d’écran ni vos fichiers.",
|
|
133
136
|
visibleLocked: "Seulement tant que le retour est encore ouvert.",
|
|
137
|
+
page: (page) => `Page ${n(page)}`,
|
|
134
138
|
},
|
|
135
139
|
feedbackNotificationTypes: {
|
|
136
140
|
answered: "Réponses à vos retours",
|
|
@@ -1729,6 +1733,14 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
1729
1733
|
payNothing: "Il n’y a rien à payer ici. Pour choisir une formule, revenez à l’application.",
|
|
1730
1734
|
payFailed: "Le paiement n’a pas pu s’ouvrir. Veuillez revenir en arrière et réessayer dans un instant.",
|
|
1731
1735
|
payBack: "Le paiement a été fermé. Vous pouvez revenir en arrière, ou recharger cette page pour le rouvrir.",
|
|
1736
|
+
payDone: "Paiement effectué. Vous pouvez fermer cette page.",
|
|
1737
|
+
// 0.39 (§15.2.10): PlanSwitchConfirm.
|
|
1738
|
+
switchTitle: "Changer de formule",
|
|
1739
|
+
switchFromTo: (from, to) => `De ${from} à ${to}`,
|
|
1740
|
+
switchChargedNow: "Débité maintenant",
|
|
1741
|
+
switchCredited: "Crédité sur vos prochains paiements",
|
|
1742
|
+
switchNextCharge: (date) => `Prochain prélèvement le ${date}`,
|
|
1743
|
+
switchConfirm: "Changer de formule",
|
|
1732
1744
|
waitingChanges: (count) =>
|
|
1733
1745
|
`${n(count)} ${plural(count, "modification en attente", "modifications en attente")} d’une formule`,
|
|
1734
1746
|
// "Abandonner", as `wizard.cancelConfirmLabel`.
|
|
@@ -1738,10 +1750,12 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
1738
1750
|
// §14.2: server-kit 0.7's refusals. "Paiement et factures", as `manage`.
|
|
1739
1751
|
providerUnavailable:
|
|
1740
1752
|
"Le prestataire de paiement est injoignable pour le moment. Veuillez réessayer dans un instant.",
|
|
1741
|
-
alreadySubscribed:
|
|
1742
|
-
"Vous avez déjà un abonnement. Pour changer de formule, allez dans «\u202fPaiement et factures\u202f».",
|
|
1753
|
+
alreadySubscribed: "Vous avez déjà un abonnement. Changez de formule ci-dessus.",
|
|
1743
1754
|
planNotSold:
|
|
1744
1755
|
"Cette formule n’est pas proposée pour cette période de facturation ou cette devise. Veuillez en choisir une autre.",
|
|
1756
|
+
// 0.39 (§15.2.10): the plan switch's refusals.
|
|
1757
|
+
notSubscribed: "Aucun abonnement en cours à modifier. Choisissez une formule pour vous abonner.",
|
|
1758
|
+
planUnchanged: "C’est déjà votre formule. Choisissez une autre formule ou une autre période de facturation.",
|
|
1745
1759
|
},
|
|
1746
1760
|
// 0.33.0 — docs/billing-harmonization.md §14.12: the operator's plan parts, "formule"
|
|
1747
1761
|
// as in `billing`. "Vous".
|
package/src/i18n/locales/hu.ts
CHANGED
|
@@ -101,6 +101,9 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
101
101
|
statusChanged: (status, title) => `„${status}” állapotra állítva: ${title}`,
|
|
102
102
|
statusUndo: "Visszavonás",
|
|
103
103
|
statusRestored: (status, title) => `Vissza „${status}” állapotra: ${title}`,
|
|
104
|
+
commentFailed: "A hozzászólást nem sikerült elküldeni.",
|
|
105
|
+
voteFailed: "A szavazatot nem sikerült menteni.",
|
|
106
|
+
replyFailed: "A választ nem sikerült elküldeni.",
|
|
104
107
|
},
|
|
105
108
|
feedbackMenu: {
|
|
106
109
|
trigger: "Visszajelzés küldése",
|
|
@@ -130,6 +133,7 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
130
133
|
visibleToOthers: "Mások számára látható",
|
|
131
134
|
visibleHint: "Mások a címet és a szöveget látják, a képernyőképeit és fájljait soha.",
|
|
132
135
|
visibleLocked: "Csak amíg a bejelentés nyitott.",
|
|
136
|
+
page: (page) => `${n(page)}. oldal`,
|
|
133
137
|
},
|
|
134
138
|
feedbackNotificationTypes: {
|
|
135
139
|
answered: "Válaszok a bejelentéseire",
|
|
@@ -1698,6 +1702,14 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
1698
1702
|
payNothing: "Itt nincs mit kifizetni. Csomag választásához térjen vissza az alkalmazásba.",
|
|
1699
1703
|
payFailed: "A fizetést nem sikerült megnyitni. Kérjük, lépjen vissza, és próbálja újra egy kis idő múlva.",
|
|
1700
1704
|
payBack: "A fizetés bezárult. Visszaléphet, vagy a megnyitásához töltse újra ezt az oldalt.",
|
|
1705
|
+
payDone: "A fizetés sikerült. Bezárhatja ezt az oldalt.",
|
|
1706
|
+
// 0.39 (§15.2.10): PlanSwitchConfirm.
|
|
1707
|
+
switchTitle: "Csomag módosítása",
|
|
1708
|
+
switchFromTo: (from, to) => `${from} helyett ${to}`,
|
|
1709
|
+
switchChargedNow: "Most terhelt összeg",
|
|
1710
|
+
switchCredited: "A következő terhelésekből levonva",
|
|
1711
|
+
switchNextCharge: (date) => `Következő terhelés: ${date}`,
|
|
1712
|
+
switchConfirm: "Csomag módosítása",
|
|
1701
1713
|
// No plural after a numeral (convention 2).
|
|
1702
1714
|
waitingChanges: (count) => `${n(count)} módosítás csomagra vár`,
|
|
1703
1715
|
// "Elvetés", as `wizard.cancelConfirmLabel`.
|
|
@@ -1706,9 +1718,12 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
1706
1718
|
disabled: "Az előfizetés itt nem érhető el.",
|
|
1707
1719
|
// §14.2: server-kit 0.7's refusals. "Fizetés és számlák", as `manage`.
|
|
1708
1720
|
providerUnavailable: "A fizetési szolgáltató jelenleg nem érhető el. Kérjük, próbálja újra egy kis idő múlva.",
|
|
1709
|
-
alreadySubscribed: "Már van előfizetése. A
|
|
1721
|
+
alreadySubscribed: "Már van előfizetése. A csomagot fent módosíthatja.",
|
|
1710
1722
|
planNotSold:
|
|
1711
1723
|
"Ez a csomag ehhez a számlázási időszakhoz vagy pénznemhez nem érhető el. Kérjük, válasszon másikat.",
|
|
1724
|
+
// 0.39 (§15.2.10): the plan switch's refusals.
|
|
1725
|
+
notSubscribed: "Nincs futó előfizetés, amelyet módosítani lehetne. Előfizetéshez válasszon egy csomagot.",
|
|
1726
|
+
planUnchanged: "Ez már az Ön csomagja. Válasszon másik csomagot vagy számlázási időszakot.",
|
|
1712
1727
|
},
|
|
1713
1728
|
// 0.33.0 — docs/billing-harmonization.md §14.12: the operator's plan parts, "csomag"
|
|
1714
1729
|
// as in `billing`. A plan's name takes no case ending: it follows a colon or an arrow.
|
package/src/i18n/locales/it.ts
CHANGED
|
@@ -104,6 +104,9 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
104
104
|
statusChanged: (status, title) => `Impostato su «${status}»: ${title}`,
|
|
105
105
|
statusUndo: "Annulla",
|
|
106
106
|
statusRestored: (status, title) => `Tornato a «${status}»: ${title}`,
|
|
107
|
+
commentFailed: "Non è stato possibile pubblicare il commento.",
|
|
108
|
+
voteFailed: "Non è stato possibile salvare il Suo voto.",
|
|
109
|
+
replyFailed: "Non è stato possibile inviare la risposta.",
|
|
107
110
|
},
|
|
108
111
|
feedbackMenu: {
|
|
109
112
|
trigger: "Invia feedback",
|
|
@@ -133,6 +136,7 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
133
136
|
visibleToOthers: "Visibile agli altri",
|
|
134
137
|
visibleHint: "Le altre persone vedono il titolo e il testo, mai i Suoi screenshot o file.",
|
|
135
138
|
visibleLocked: "Solo finché la segnalazione è ancora aperta.",
|
|
139
|
+
page: (page) => `Pagina ${n(page)}`,
|
|
136
140
|
},
|
|
137
141
|
feedbackNotificationTypes: {
|
|
138
142
|
answered: "Risposte alle Sue segnalazioni",
|
|
@@ -1711,6 +1715,14 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
1711
1715
|
payNothing: "Qui non c’è nulla da pagare. Per scegliere un piano, torni all’app.",
|
|
1712
1716
|
payFailed: "Non è stato possibile aprire il pagamento. Torni indietro e riprovi tra un momento.",
|
|
1713
1717
|
payBack: "Il pagamento è stato chiuso. Può tornare indietro, oppure ricaricare questa pagina per riaprirlo.",
|
|
1718
|
+
payDone: "Pagamento completato. Può chiudere questa pagina.",
|
|
1719
|
+
// 0.39 (§15.2.10): PlanSwitchConfirm.
|
|
1720
|
+
switchTitle: "Cambia piano",
|
|
1721
|
+
switchFromTo: (from, to) => `Da ${from} a ${to}`,
|
|
1722
|
+
switchChargedNow: "Addebitato ora",
|
|
1723
|
+
switchCredited: "Accreditato sui prossimi addebiti",
|
|
1724
|
+
switchNextCharge: (date) => `Prossimo addebito il ${date}`,
|
|
1725
|
+
switchConfirm: "Cambia piano",
|
|
1714
1726
|
waitingChanges: (count) =>
|
|
1715
1727
|
`${n(count)} ${plural(count, "modifica in attesa", "modifiche in attesa")} di un piano`,
|
|
1716
1728
|
// "Scarta", as `wizard.cancelConfirmLabel`.
|
|
@@ -1719,9 +1731,12 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
1719
1731
|
disabled: "Gli abbonamenti non sono disponibili qui.",
|
|
1720
1732
|
// §14.2: server-kit 0.7's refusals. "Pagamento e fatture", as `manage`. "Lei".
|
|
1721
1733
|
providerUnavailable: "Il fornitore dei pagamenti non è raggiungibile al momento. Riprovi tra un momento.",
|
|
1722
|
-
alreadySubscribed: "Ha già un abbonamento.
|
|
1734
|
+
alreadySubscribed: "Ha già un abbonamento. Cambi piano qui sopra.",
|
|
1723
1735
|
planNotSold:
|
|
1724
1736
|
"Questo piano non è disponibile per questo periodo di fatturazione o questa valuta. Ne scelga un altro.",
|
|
1737
|
+
// 0.39 (§15.2.10): the plan switch's refusals.
|
|
1738
|
+
notSubscribed: "Non c’è nessun abbonamento attivo da modificare. Scelga un piano per abbonarsi.",
|
|
1739
|
+
planUnchanged: "Questo è già il Suo piano. Scelga un altro piano o un altro periodo di fatturazione.",
|
|
1725
1740
|
},
|
|
1726
1741
|
// 0.33.0 — docs/billing-harmonization.md §14.12: the operator's plan parts, "piano" as
|
|
1727
1742
|
// in `billing`. "Lei" in sentences, the imperative on the title and the button.
|
package/src/i18n/locales/zh.ts
CHANGED
|
@@ -94,6 +94,9 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
94
94
|
statusChanged: (status, title) => `已设为“${status}”:${title}`,
|
|
95
95
|
statusUndo: "撤销",
|
|
96
96
|
statusRestored: (status, title) => `已恢复为“${status}”:${title}`,
|
|
97
|
+
commentFailed: "无法发表评论。",
|
|
98
|
+
voteFailed: "无法保存您的投票。",
|
|
99
|
+
replyFailed: "无法发送回复。",
|
|
97
100
|
},
|
|
98
101
|
feedbackMenu: {
|
|
99
102
|
trigger: "发送反馈",
|
|
@@ -123,6 +126,7 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
123
126
|
visibleToOthers: "对他人可见",
|
|
124
127
|
visibleHint: "其他用户可以看到标题和正文,绝不会看到您的截图或文件。",
|
|
125
128
|
visibleLocked: "仅在反馈仍处于打开状态时可更改。",
|
|
129
|
+
page: (page) => `第 ${n(page)} 页`,
|
|
126
130
|
},
|
|
127
131
|
feedbackNotificationTypes: {
|
|
128
132
|
answered: "您的反馈收到的回复",
|
|
@@ -1625,6 +1629,14 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
1625
1629
|
payNothing: "这里没有需要支付的款项。如需选择套餐,请返回应用。",
|
|
1626
1630
|
payFailed: "无法打开支付页面。请返回后稍候再试。",
|
|
1627
1631
|
payBack: "支付页面已关闭。您可以返回,或重新加载此页面以再次打开。",
|
|
1632
|
+
payDone: "付款已完成。您可以关闭此页面。",
|
|
1633
|
+
// 0.39 (§15.2.10): PlanSwitchConfirm.
|
|
1634
|
+
switchTitle: "更改套餐",
|
|
1635
|
+
switchFromTo: (from, to) => `从 ${from} 更改为 ${to}`,
|
|
1636
|
+
switchChargedNow: "立即扣款",
|
|
1637
|
+
switchCredited: "抵扣后续扣款",
|
|
1638
|
+
switchNextCharge: (date) => `下次扣款日期:${date}`,
|
|
1639
|
+
switchConfirm: "更改套餐",
|
|
1628
1640
|
waitingChanges: (count) => `${n(count)} 项修改正在等待套餐`,
|
|
1629
1641
|
// "放弃", as `wizard.cancelConfirmLabel`.
|
|
1630
1642
|
discardWaiting: "放弃等待中的修改",
|
|
@@ -1632,8 +1644,11 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
1632
1644
|
disabled: "此处不提供订阅。",
|
|
1633
1645
|
// §14.2: server-kit 0.7's refusals. "付款与发票", as `manage`.
|
|
1634
1646
|
providerUnavailable: "暂时无法连接支付服务商,请稍后再试。",
|
|
1635
|
-
alreadySubscribed: "
|
|
1647
|
+
alreadySubscribed: "您已有订阅。请在上方更改套餐。",
|
|
1636
1648
|
planNotSold: "该套餐不支持此计费周期或货币,请选择其他套餐。",
|
|
1649
|
+
// 0.39 (§15.2.10): the plan switch's refusals.
|
|
1650
|
+
notSubscribed: "没有可更改的有效订阅。请选择一个套餐进行订阅。",
|
|
1651
|
+
planUnchanged: "这已经是您当前的套餐。请选择其他套餐或计费周期。",
|
|
1637
1652
|
},
|
|
1638
1653
|
// 0.33.0 — docs/billing-harmonization.md §14.12: the operator's plan parts, "套餐" as
|
|
1639
1654
|
// in `billing`. "测试版", as `landing.beta`.
|
package/src/i18n/review.ts
CHANGED
|
@@ -216,6 +216,7 @@ export const KIT_LABEL_SAMPLES: Readonly<Record<string, readonly (readonly unkno
|
|
|
216
216
|
"feedbackPublic.comments": one,
|
|
217
217
|
"feedbackPublic.votes": one,
|
|
218
218
|
"feedbackPublic.filedBy": [["{{name}}"]],
|
|
219
|
+
"feedbackPublic.page": [[3]],
|
|
219
220
|
"accountSettings.passkeys.renameItem": [["{{name}}"]],
|
|
220
221
|
"accountSettings.passkeys.renameField": [["{{name}}"]],
|
|
221
222
|
"accountSettings.passkeys.deleteItem": [["{{name}}"]],
|
|
@@ -389,6 +390,9 @@ export const KIT_LABEL_SAMPLES: Readonly<Record<string, readonly (readonly unkno
|
|
|
389
390
|
"billing.waitingChanges": one,
|
|
390
391
|
// 0.33.0: the limit's figure line (§14.11) and the operator's plan parts (§14.12).
|
|
391
392
|
"billing.limitUsageLine": [["{{dimension}}", "{{used}}", "{{limit}}"]],
|
|
393
|
+
// 0.39: PlanSwitchConfirm's two lines with figures (§15.2.10).
|
|
394
|
+
"billing.switchFromTo": [["{{from}}", "{{to}}"]],
|
|
395
|
+
"billing.switchNextCharge": [["{{date}}"]],
|
|
392
396
|
"planChange.current": [["{{plan}}"]],
|
|
393
397
|
"planChange.changed": [["{{from}}", "{{to}}"]],
|
|
394
398
|
"planChange.set": [["{{to}}"]],
|
package/src/index.ts
CHANGED
|
@@ -79,6 +79,7 @@ export type {
|
|
|
79
79
|
ReviewStatus,
|
|
80
80
|
TranslationRow,
|
|
81
81
|
ApiTranslationReview,
|
|
82
|
+
ApiTranslationReviewsResponse,
|
|
82
83
|
ApiTranslationReviewWrite,
|
|
83
84
|
TranslationRowsInput,
|
|
84
85
|
TranslationSummary,
|
|
@@ -842,11 +843,18 @@ export type { CheckoutOverview, CheckoutProcessingOptions } from "./billing/chec
|
|
|
842
843
|
// The link to the pay page and Paddle's locale (§14.4); the page itself ships as dist/pay/.
|
|
843
844
|
export { PAY_PAGE_LANG_PARAM, paddleLocale, payPageUrl } from "./billing/pay-page";
|
|
844
845
|
export type { PaddleEnvironment } from "./billing/pay-page";
|
|
846
|
+
// 0.39 (§15.2.6): the apps every pay page serves, by their `billing_app` tag.
|
|
847
|
+
export { PAY_PAGE_APPS } from "./billing/pay-page";
|
|
848
|
+
export type { PayPageApp } from "./billing/pay-page";
|
|
845
849
|
// The API's shapes the parts read, server-kit 0.7's (§4, §14.5), and the plan limit as
|
|
846
850
|
// a toast (§14.11).
|
|
847
851
|
export type { BillingOverview, SubscriptionSource, PortalTarget, PortalRequest } from "./billing/billing-overview";
|
|
848
852
|
export { usePlanLimitToast } from "./billing/plan-limit-toast";
|
|
849
853
|
export type { PlanLimitToastOptions } from "./billing/plan-limit-toast";
|
|
854
|
+
// 0.39 (§15.2.10): the payer's plan switch, its shapes, and what the payer pays.
|
|
855
|
+
export { PlanSwitchConfirm } from "./billing/plan-switch";
|
|
856
|
+
export type { PlanSwitchConfirmProps, PlanSwitchSide } from "./billing/plan-switch";
|
|
857
|
+
export type { PaidPrice, PlanSwitchRequest, PlanSwitchPreview } from "./billing/billing-overview";
|
|
850
858
|
// The operator's plan parts (§14.12) are admin/plan-change, in the admin section.
|
|
851
859
|
|
|
852
860
|
// ── settings ─────────────────────────────────────────────────────────────────
|