@mrrocket/sdk 0.17.0 → 0.21.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/CHANGELOG.md +30 -1
- package/README.md +24 -1
- package/dist/api-client.d.ts +28 -4
- package/dist/api-client.js +30 -13
- package/dist/api-client.js.map +1 -1
- package/dist/browser/mrrocket-flows.js +15 -3
- package/dist/browser/mrrocket-messenger.js +38 -5
- package/dist/browser/mrrocket.js +1 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +2 -1
- package/dist/browser.js.map +1 -1
- package/dist/client.d.ts +28 -3
- package/dist/client.js +37 -5
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +3 -1
- package/dist/context.js.map +1 -1
- package/dist/core.d.ts +7 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/feedback.js +161 -119
- package/dist/feedback.js.map +1 -1
- package/dist/finish-web.d.ts +18 -0
- package/dist/finish-web.js +139 -0
- package/dist/finish-web.js.map +1 -0
- package/dist/flows-ui.d.ts +1 -10
- package/dist/flows-ui.js +175 -48
- package/dist/flows-ui.js.map +1 -1
- package/dist/flows-web.d.ts +8 -1
- package/dist/flows-web.js +10 -1
- package/dist/flows-web.js.map +1 -1
- package/dist/flows.d.ts +193 -9
- package/dist/flows.js +284 -38
- package/dist/flows.js.map +1 -1
- package/dist/i18n.d.ts +22 -0
- package/dist/i18n.js +74 -0
- package/dist/i18n.js.map +1 -0
- package/dist/icons.d.ts +24 -0
- package/dist/icons.js +61 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/messenger-ui.d.ts +9 -3
- package/dist/messenger-ui.js +388 -191
- package/dist/messenger-ui.js.map +1 -1
- package/dist/messenger.d.ts +3 -1
- package/dist/messenger.js +3 -2
- package/dist/messenger.js.map +1 -1
- package/dist/onboarding-state.d.ts +23 -0
- package/dist/onboarding-state.js +43 -0
- package/dist/onboarding-state.js.map +1 -0
- package/dist/paywall.js +2 -1
- package/dist/paywall.js.map +1 -1
- package/dist/react-native/index.d.cts +239 -19
- package/dist/react-native/index.d.ts +239 -19
- package/dist/react-native/index.js +1305 -518
- package/dist/react-native/index.js.map +1 -1
- package/dist/server.d.ts +4 -2
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/styles-css.d.ts +1 -1
- package/dist/styles-css.js +35 -2
- package/dist/styles-css.js.map +1 -1
- package/dist/survey.js +18 -14
- package/dist/survey.js.map +1 -1
- package/dist/ui.d.ts +2 -0
- package/dist/ui.js +15 -12
- package/dist/ui.js.map +1 -1
- package/package.json +6 -3
package/dist/feedback.js
CHANGED
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
useApi
|
|
8
8
|
} from "./api.js";
|
|
9
9
|
import { useCtx } from "./context.js";
|
|
10
|
-
import {
|
|
10
|
+
import { currentLocale, t, tf } from "./i18n.js";
|
|
11
|
+
import { Chat, ChevronUp, Cross, Moon, Plus, Root, Search, StatusPill, Sun, VoteButton, similarPosts, timeAgo, useEscape, votesWord } from "./ui.js";
|
|
11
12
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
13
|
var whoKey = (apiKey) => `ckw-board-who:${apiKey}`;
|
|
13
14
|
var readWho = (apiKey) => {
|
|
@@ -101,20 +102,21 @@ var useFeedbackList = (api, opts) => {
|
|
|
101
102
|
patch(post.id, flip);
|
|
102
103
|
as.vote(post.id).then((r) => patch(post.id, (p) => ({ ...p, voted: r.voted, votes: r.votes }))).catch((e) => {
|
|
103
104
|
patch(post.id, flip);
|
|
104
|
-
setError(
|
|
105
|
+
setError(`${t("Your vote was not saved.")} ${e.message}`);
|
|
105
106
|
});
|
|
106
107
|
},
|
|
107
108
|
[api, patch]
|
|
108
109
|
);
|
|
109
|
-
return { posts, setPosts, patch, boards, product, loading, error, setError, vote, reload: () => setTick((
|
|
110
|
+
return { posts, setPosts, patch, boards, product, loading, error, setError, vote, reload: () => setTick((t2) => t2 + 1) };
|
|
110
111
|
};
|
|
112
|
+
var authorName = (author) => author === "Team" ? t("Team") : author === "Anonymous" ? t("Anonymous") : author;
|
|
111
113
|
var BOARD_TONE = { feature: "blue", bug: "red", integration: "violet", improvement: "green" };
|
|
112
114
|
var TypeChip = ({ board, boards }) => /* @__PURE__ */ jsx("span", { className: "ckw-type", "data-tone": BOARD_TONE[board] ?? "gray", children: boards.find((b) => b.id === board)?.label ?? board });
|
|
113
115
|
var Avatar = ({ name, team }) => /* @__PURE__ */ jsx("span", { className: "ckw-av", "data-team": team || void 0, "aria-hidden": "true", children: (name.trim()[0] ?? "?").toUpperCase() });
|
|
114
116
|
var Skeleton = ({ rows = 3 }) => /* @__PURE__ */ jsx("div", { "aria-hidden": "true", children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx("div", { className: "ckw-skel" }, i)) });
|
|
115
117
|
var ErrorBar = ({ message, onRetry, onClose }) => /* @__PURE__ */ jsxs("div", { className: "ckw-error", role: "alert", children: [
|
|
116
118
|
/* @__PURE__ */ jsx("span", { children: message }),
|
|
117
|
-
onRetry ? /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn", onClick: onRetry, children: "Retry" }) : onClose && /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: onClose, "aria-label": "Dismiss", children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
119
|
+
onRetry ? /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn", onClick: onRetry, children: t("Retry") }) : onClose && /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: onClose, "aria-label": t("Dismiss"), children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
118
120
|
] });
|
|
119
121
|
var Modal = ({ title, onClose, children }) => {
|
|
120
122
|
const box = useRef(null);
|
|
@@ -137,7 +139,7 @@ var Modal = ({ title, onClose, children }) => {
|
|
|
137
139
|
return /* @__PURE__ */ jsx("div", { className: "ckw-scrim", onMouseDown: (e) => e.target === e.currentTarget && onClose(), children: /* @__PURE__ */ jsxs("div", { ref: box, className: "ckw-modal", role: "dialog", "aria-modal": "true", "aria-labelledby": id, onKeyDown: trap, children: [
|
|
138
140
|
/* @__PURE__ */ jsxs("div", { className: "ckw-modal-head", children: [
|
|
139
141
|
/* @__PURE__ */ jsx("h2", { id, children: title }),
|
|
140
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-icon-btn", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
142
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-icon-btn", onClick: onClose, "aria-label": t("Close"), children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
141
143
|
] }),
|
|
142
144
|
children
|
|
143
145
|
] }) });
|
|
@@ -147,7 +149,7 @@ var IdentityFields = ({ name, email, setName, setEmail }) => {
|
|
|
147
149
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
148
150
|
/* @__PURE__ */ jsxs("div", { className: "ckw-pair", children: [
|
|
149
151
|
/* @__PURE__ */ jsxs("div", { className: "ckw-field", children: [
|
|
150
|
-
/* @__PURE__ */ jsx("label", { className: "ckw-label", htmlFor: `${id}-n`, children: "Your name" }),
|
|
152
|
+
/* @__PURE__ */ jsx("label", { className: "ckw-label", htmlFor: `${id}-n`, children: t("Your name") }),
|
|
151
153
|
/* @__PURE__ */ jsx(
|
|
152
154
|
"input",
|
|
153
155
|
{
|
|
@@ -162,7 +164,7 @@ var IdentityFields = ({ name, email, setName, setEmail }) => {
|
|
|
162
164
|
)
|
|
163
165
|
] }),
|
|
164
166
|
/* @__PURE__ */ jsxs("div", { className: "ckw-field", children: [
|
|
165
|
-
/* @__PURE__ */ jsx("label", { className: "ckw-label", htmlFor: `${id}-e`, children: "Email" }),
|
|
167
|
+
/* @__PURE__ */ jsx("label", { className: "ckw-label", htmlFor: `${id}-e`, children: t("Email") }),
|
|
166
168
|
/* @__PURE__ */ jsx(
|
|
167
169
|
"input",
|
|
168
170
|
{
|
|
@@ -178,7 +180,7 @@ var IdentityFields = ({ name, email, setName, setEmail }) => {
|
|
|
178
180
|
)
|
|
179
181
|
] })
|
|
180
182
|
] }),
|
|
181
|
-
/* @__PURE__ */ jsx("p", { className: "ckw-fine", children: "Others see your first name and last initial. Your email is only for updates on what you posted or voted for." })
|
|
183
|
+
/* @__PURE__ */ jsx("p", { className: "ckw-fine", children: t("Others see your first name and last initial. Your email is only for updates on what you posted or voted for.") })
|
|
182
184
|
] });
|
|
183
185
|
};
|
|
184
186
|
var IdentityDialog = ({ identity }) => {
|
|
@@ -187,7 +189,7 @@ var IdentityDialog = ({ identity }) => {
|
|
|
187
189
|
const ok = name.trim().length > 0 && EMAIL.test(email.trim());
|
|
188
190
|
const run = identity.asking;
|
|
189
191
|
if (!run) return null;
|
|
190
|
-
return /* @__PURE__ */ jsx(Modal, { title: "Before you vote or comment", onClose: identity.cancel, children: /* @__PURE__ */ jsxs(
|
|
192
|
+
return /* @__PURE__ */ jsx(Modal, { title: t("Before you vote or comment"), onClose: identity.cancel, children: /* @__PURE__ */ jsxs(
|
|
191
193
|
"form",
|
|
192
194
|
{
|
|
193
195
|
className: "ckw-modal-body",
|
|
@@ -201,8 +203,8 @@ var IdentityDialog = ({ identity }) => {
|
|
|
201
203
|
children: [
|
|
202
204
|
/* @__PURE__ */ jsx(IdentityFields, { name, email, setName, setEmail }),
|
|
203
205
|
/* @__PURE__ */ jsxs("div", { className: "ckw-actions", children: [
|
|
204
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: identity.cancel, children: "Cancel" }),
|
|
205
|
-
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: !ok, children: "Continue" })
|
|
206
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: identity.cancel, children: t("Cancel") }),
|
|
207
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: !ok, children: t("Continue") })
|
|
206
208
|
] })
|
|
207
209
|
]
|
|
208
210
|
}
|
|
@@ -249,7 +251,7 @@ var SubmitForm = ({
|
|
|
249
251
|
};
|
|
250
252
|
return /* @__PURE__ */ jsxs("form", { className: bare ? "ckw-modal-body" : "ckw-form", onSubmit: submit, children: [
|
|
251
253
|
/* @__PURE__ */ jsxs("div", { className: "ckw-field", children: [
|
|
252
|
-
/* @__PURE__ */ jsx("label", { className: "ckw-label", htmlFor: `${id}-t`, children: "Title" }),
|
|
254
|
+
/* @__PURE__ */ jsx("label", { className: "ckw-label", htmlFor: `${id}-t`, children: t("Title") }),
|
|
253
255
|
/* @__PURE__ */ jsx(
|
|
254
256
|
"input",
|
|
255
257
|
{
|
|
@@ -260,21 +262,22 @@ var SubmitForm = ({
|
|
|
260
262
|
required: true,
|
|
261
263
|
autoFocus: true,
|
|
262
264
|
onChange: (e) => setTitle(e.target.value),
|
|
263
|
-
placeholder: "Short, specific summary"
|
|
265
|
+
placeholder: t("Short, specific summary")
|
|
264
266
|
}
|
|
265
267
|
)
|
|
266
268
|
] }),
|
|
267
269
|
dupes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ckw-dupes", role: "status", children: [
|
|
268
|
-
/* @__PURE__ */ jsx("p", { children: "Similar requests. Vote instead of adding a duplicate:" }),
|
|
270
|
+
/* @__PURE__ */ jsx("p", { children: t("Similar requests. Vote instead of adding a duplicate:") }),
|
|
269
271
|
dupes.map((d) => /* @__PURE__ */ jsxs("div", { className: "ckw-dupe", children: [
|
|
270
272
|
/* @__PURE__ */ jsx("span", { title: d.title, children: d.title }),
|
|
271
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn", disabled: d.voted, onClick: () => onVote(d), children: d.voted ? "Voted" : "Vote instead" })
|
|
273
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn", disabled: d.voted, onClick: () => onVote(d), children: d.voted ? t("Voted") : t("Vote instead") })
|
|
272
274
|
] }, d.id))
|
|
273
275
|
] }),
|
|
274
276
|
!compact && /* @__PURE__ */ jsxs("div", { className: "ckw-field", children: [
|
|
275
277
|
/* @__PURE__ */ jsxs("label", { className: "ckw-label", htmlFor: `${id}-b`, children: [
|
|
276
|
-
"Details
|
|
277
|
-
|
|
278
|
+
t("Details"),
|
|
279
|
+
" ",
|
|
280
|
+
/* @__PURE__ */ jsx("span", { className: "ckw-opt-l", children: t("optional") })
|
|
278
281
|
] }),
|
|
279
282
|
/* @__PURE__ */ jsx(
|
|
280
283
|
"textarea",
|
|
@@ -284,19 +287,19 @@ var SubmitForm = ({
|
|
|
284
287
|
value: body,
|
|
285
288
|
maxLength: 2e3,
|
|
286
289
|
onChange: (e) => setBody(e.target.value),
|
|
287
|
-
placeholder: "What are you trying to do? What gets in the way?"
|
|
290
|
+
placeholder: t("What are you trying to do? What gets in the way?")
|
|
288
291
|
}
|
|
289
292
|
)
|
|
290
293
|
] }),
|
|
291
294
|
boards.length > 1 && /* @__PURE__ */ jsxs("div", { className: "ckw-field", children: [
|
|
292
|
-
/* @__PURE__ */ jsx("span", { className: "ckw-label", id: `${id}-c`, children: "Type" }),
|
|
295
|
+
/* @__PURE__ */ jsx("span", { className: "ckw-label", id: `${id}-c`, children: t("Type") }),
|
|
293
296
|
/* @__PURE__ */ jsx("div", { className: "ckw-chips", role: "radiogroup", "aria-labelledby": `${id}-c`, style: { marginBottom: 0 }, children: boards.map((b) => /* @__PURE__ */ jsx("button", { type: "button", role: "radio", "aria-checked": chosen === b.id, className: "ckw-chip", onClick: () => setBoard(b.id), children: b.label }, b.id)) })
|
|
294
297
|
] }),
|
|
295
298
|
ask && /* @__PURE__ */ jsx(IdentityFields, { name, email, setName, setEmail }),
|
|
296
299
|
error && /* @__PURE__ */ jsx("div", { className: "ckw-error", role: "alert", children: error }),
|
|
297
300
|
/* @__PURE__ */ jsxs("div", { className: "ckw-actions", children: [
|
|
298
|
-
onCancel && /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: onCancel, children: "Cancel" }),
|
|
299
|
-
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: busy || !ready, children: busy ? "Sending\u2026" : "Submit" })
|
|
301
|
+
onCancel && /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: onCancel, children: t("Cancel") }),
|
|
302
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: busy || !ready, children: busy ? t("Sending\u2026") : t("Submit") })
|
|
300
303
|
] })
|
|
301
304
|
] });
|
|
302
305
|
};
|
|
@@ -313,12 +316,12 @@ var PostCard = ({
|
|
|
313
316
|
/* @__PURE__ */ jsxs("div", { className: "ckw-meta", children: [
|
|
314
317
|
/* @__PURE__ */ jsx(TypeChip, { board: post.board, boards }),
|
|
315
318
|
post.status !== "review" && /* @__PURE__ */ jsx(StatusPill, { status: post.status }),
|
|
316
|
-
/* @__PURE__ */ jsxs("span", { className: "ckw-stat", "aria-label":
|
|
319
|
+
/* @__PURE__ */ jsxs("span", { className: "ckw-stat", "aria-label": post.comments === 1 ? t("1 comment") : tf("{n} comments", { n: post.comments }), children: [
|
|
317
320
|
/* @__PURE__ */ jsx(Chat, {}),
|
|
318
321
|
" ",
|
|
319
322
|
post.comments
|
|
320
323
|
] }),
|
|
321
|
-
/* @__PURE__ */ jsx("span", { className: "ckw-dot-sep", children: [post.author, timeAgo(post.createdAt)].filter(Boolean).join(" \xB7 ") })
|
|
324
|
+
/* @__PURE__ */ jsx("span", { className: "ckw-dot-sep", children: [post.author && authorName(post.author), timeAgo(post.createdAt)].filter(Boolean).join(" \xB7 ") })
|
|
322
325
|
] })
|
|
323
326
|
] })
|
|
324
327
|
] });
|
|
@@ -331,28 +334,53 @@ var Requests = ({
|
|
|
331
334
|
q,
|
|
332
335
|
onOpen,
|
|
333
336
|
onVote,
|
|
334
|
-
onNew
|
|
337
|
+
onNew,
|
|
338
|
+
roadmap,
|
|
339
|
+
onRoadmap
|
|
335
340
|
}) => {
|
|
336
341
|
const { posts, boards } = list;
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
/* @__PURE__ */ jsx("
|
|
342
|
-
boards.
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
/* @__PURE__ */
|
|
348
|
-
|
|
349
|
-
/* @__PURE__ */
|
|
350
|
-
|
|
351
|
-
/* @__PURE__ */ jsx(
|
|
352
|
-
"
|
|
342
|
+
const side = !!roadmap || boards.length > 1;
|
|
343
|
+
return /* @__PURE__ */ jsx("div", { className: "ckw-req", children: /* @__PURE__ */ jsxs("div", { className: "ckw-req-grid", "data-side": side || void 0, children: [
|
|
344
|
+
/* @__PURE__ */ jsxs("div", { className: "ckw-req-main", children: [
|
|
345
|
+
/* @__PURE__ */ jsxs("div", { className: "ckw-tools", children: [
|
|
346
|
+
/* @__PURE__ */ jsx("div", { className: "ckw-seg", role: "group", "aria-label": t("Sort"), children: ["top", "new"].map((s) => /* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": sort === s, onClick: () => setSort(s), children: s === "top" ? t("Top") : t("New") }, s)) }),
|
|
347
|
+
boards.length > 1 && /* @__PURE__ */ jsxs("div", { className: "ckw-chips ckw-chips-inline", role: "group", "aria-label": t("Type"), children: [
|
|
348
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-chip", "aria-pressed": !board, onClick: () => setBoard(void 0), children: t("All") }),
|
|
349
|
+
boards.map((b) => /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-chip", "aria-pressed": board === b.id, onClick: () => setBoard(b.id), children: b.label }, b.id))
|
|
350
|
+
] })
|
|
351
|
+
] }),
|
|
352
|
+
/* @__PURE__ */ jsx("div", { "aria-live": "polite", "aria-busy": list.loading, children: list.loading && posts.length === 0 ? /* @__PURE__ */ jsx(Skeleton, {}) : posts.length === 0 && !list.error ? (
|
|
353
|
+
// Things' empty look (owner, 2026-10-21): a large faint glyph, one line and the one next step, no frame.
|
|
354
|
+
/* @__PURE__ */ jsxs("div", { className: "ckw-empty", children: [
|
|
355
|
+
/* @__PURE__ */ jsx(EmptyGlyph, {}),
|
|
356
|
+
/* @__PURE__ */ jsx("p", { children: q ? t("No request matches your search.") : board ? t("Nothing of this type yet.") : t("No requests yet.") }),
|
|
357
|
+
!q && /* @__PURE__ */ jsxs("button", { type: "button", className: "ckw-btn ckw-btn-primary", onClick: onNew, children: [
|
|
358
|
+
/* @__PURE__ */ jsx(Plus, {}),
|
|
359
|
+
" ",
|
|
360
|
+
t("Suggest the first one")
|
|
361
|
+
] })
|
|
353
362
|
] })
|
|
363
|
+
) : /* @__PURE__ */ jsx("ul", { className: "ckw-posts", children: posts.map((p) => /* @__PURE__ */ jsx(PostCard, { post: p, boards, onOpen, onVote }, p.id)) }) })
|
|
364
|
+
] }),
|
|
365
|
+
side && // The other half of the board, after Featurebase's and Canny's: what kind of request, and what comes next.
|
|
366
|
+
/* @__PURE__ */ jsxs("aside", { className: "ckw-req-side", children: [
|
|
367
|
+
boards.length > 1 && /* @__PURE__ */ jsxs("nav", { className: "ckw-side-part", "aria-label": t("Type"), children: [
|
|
368
|
+
/* @__PURE__ */ jsx("h2", { children: t("Type") }),
|
|
369
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-side-row", "aria-pressed": !board, onClick: () => setBoard(void 0), children: t("All") }),
|
|
370
|
+
boards.map((b) => /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-side-row", "aria-pressed": board === b.id, onClick: () => setBoard(b.id), children: b.label }, b.id))
|
|
371
|
+
] }),
|
|
372
|
+
roadmap && /* @__PURE__ */ jsxs("section", { className: "ckw-side-part", "aria-label": t("Roadmap"), children: [
|
|
373
|
+
/* @__PURE__ */ jsx("h2", { children: t("Roadmap") }),
|
|
374
|
+
COLUMNS().filter((c) => c.status !== "review").map((c) => {
|
|
375
|
+
const cards = roadmap.columns[c.status] ?? [];
|
|
376
|
+
return /* @__PURE__ */ jsxs("button", { type: "button", className: "ckw-side-row", onClick: onRoadmap, children: [
|
|
377
|
+
/* @__PURE__ */ jsx("span", { className: "ckw-sdot", "data-s": c.status }),
|
|
378
|
+
c.label,
|
|
379
|
+
/* @__PURE__ */ jsx("span", { className: "ckw-count", children: cards.length })
|
|
380
|
+
] }, c.status);
|
|
381
|
+
})
|
|
354
382
|
] })
|
|
355
|
-
|
|
383
|
+
] })
|
|
356
384
|
] }) });
|
|
357
385
|
};
|
|
358
386
|
var PostDetail = ({
|
|
@@ -382,7 +410,7 @@ var PostDetail = ({
|
|
|
382
410
|
identity.need(async (as) => {
|
|
383
411
|
setBusy(true);
|
|
384
412
|
setError("");
|
|
385
|
-
const temp = { id: `tmp-${Date.now()}`, body, author: "You", isTeam: false, postedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
413
|
+
const temp = { id: `tmp-${Date.now()}`, body, author: t("You"), isTeam: false, postedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
386
414
|
setComments((c) => [...c ?? [], temp]);
|
|
387
415
|
setText("");
|
|
388
416
|
try {
|
|
@@ -409,16 +437,17 @@ var PostDetail = ({
|
|
|
409
437
|
/* @__PURE__ */ jsx("h2", { className: "ckw-detail-title", children: post.title }),
|
|
410
438
|
/* @__PURE__ */ jsxs("div", { className: "ckw-byline", children: [
|
|
411
439
|
/* @__PURE__ */ jsx(Avatar, { name: post.author ?? "?", team: post.author === "Team" }),
|
|
412
|
-
/* @__PURE__ */ jsx("span", { children: post.author
|
|
440
|
+
/* @__PURE__ */ jsx("span", { children: post.author ? authorName(post.author) : t("Someone") }),
|
|
413
441
|
/* @__PURE__ */ jsx("span", { className: "ckw-dot-sep", children: timeAgo(post.createdAt) })
|
|
414
442
|
] }),
|
|
415
443
|
post.body && /* @__PURE__ */ jsx("p", { className: "ckw-body", children: post.body }),
|
|
416
444
|
/* @__PURE__ */ jsxs("h3", { className: "ckw-h", children: [
|
|
417
|
-
"Comments
|
|
445
|
+
t("Comments"),
|
|
446
|
+
" ",
|
|
418
447
|
/* @__PURE__ */ jsx("span", { className: "ckw-count", children: count })
|
|
419
448
|
] }),
|
|
420
449
|
/* @__PURE__ */ jsxs("form", { className: "ckw-composer", onSubmit: send, children: [
|
|
421
|
-
/* @__PURE__ */ jsx("label", { className: "ckw-sr", htmlFor: id, children: "Leave a comment" }),
|
|
450
|
+
/* @__PURE__ */ jsx("label", { className: "ckw-sr", htmlFor: id, children: t("Leave a comment") }),
|
|
422
451
|
/* @__PURE__ */ jsx(
|
|
423
452
|
"textarea",
|
|
424
453
|
{
|
|
@@ -426,28 +455,25 @@ var PostDetail = ({
|
|
|
426
455
|
className: "ckw-textarea",
|
|
427
456
|
value: text,
|
|
428
457
|
maxLength: 1e3,
|
|
429
|
-
placeholder: "Leave a comment",
|
|
458
|
+
placeholder: t("Leave a comment"),
|
|
430
459
|
onChange: (e) => setText(e.target.value)
|
|
431
460
|
}
|
|
432
461
|
),
|
|
433
462
|
/* @__PURE__ */ jsxs("div", { className: "ckw-actions", children: [
|
|
434
|
-
identity.known && identity.name && /* @__PURE__ */
|
|
435
|
-
|
|
436
|
-
identity.name
|
|
437
|
-
] }),
|
|
438
|
-
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: busy || !text.trim(), children: "Comment" })
|
|
463
|
+
identity.known && identity.name && /* @__PURE__ */ jsx("span", { className: "ckw-fine ckw-as", children: tf("Commenting as {name}", { name: identity.name }) }),
|
|
464
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: busy || !text.trim(), children: t("Comment") })
|
|
439
465
|
] })
|
|
440
466
|
] }),
|
|
441
467
|
error && /* @__PURE__ */ jsx(ErrorBar, { message: error, onClose: () => setError("") }),
|
|
442
468
|
/* @__PURE__ */ jsxs("div", { "aria-live": "polite", children: [
|
|
443
469
|
comments === null && !error && /* @__PURE__ */ jsx(Skeleton, { rows: 2 }),
|
|
444
|
-
comments?.length === 0 && /* @__PURE__ */ jsx("p", { className: "ckw-sub", children: "No comments yet." }),
|
|
470
|
+
comments?.length === 0 && /* @__PURE__ */ jsx("p", { className: "ckw-sub", children: t("No comments yet.") }),
|
|
445
471
|
comments?.map((c) => /* @__PURE__ */ jsxs("div", { className: "ckw-comment", children: [
|
|
446
472
|
/* @__PURE__ */ jsx(Avatar, { name: c.author, team: c.isTeam }),
|
|
447
473
|
/* @__PURE__ */ jsxs("div", { className: "ckw-main", children: [
|
|
448
474
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
449
|
-
/* @__PURE__ */ jsx("b", { children: c.author }),
|
|
450
|
-
c.isTeam && /* @__PURE__ */ jsx("span", { className: "ckw-team", children: "Team" }),
|
|
475
|
+
/* @__PURE__ */ jsx("b", { children: authorName(c.author) }),
|
|
476
|
+
c.isTeam && /* @__PURE__ */ jsx("span", { className: "ckw-team", children: t("Team") }),
|
|
451
477
|
/* @__PURE__ */ jsx("span", { className: "ckw-time", children: timeAgo(c.postedAt) })
|
|
452
478
|
] }),
|
|
453
479
|
/* @__PURE__ */ jsx("p", { children: c.body })
|
|
@@ -455,49 +481,49 @@ var PostDetail = ({
|
|
|
455
481
|
] }, c.id))
|
|
456
482
|
] })
|
|
457
483
|
] }),
|
|
458
|
-
/* @__PURE__ */ jsxs("aside", { className: "ckw-side", "aria-label": "About this request", children: [
|
|
484
|
+
/* @__PURE__ */ jsxs("aside", { className: "ckw-side", "aria-label": t("About this request"), children: [
|
|
459
485
|
/* @__PURE__ */ jsxs(
|
|
460
486
|
"button",
|
|
461
487
|
{
|
|
462
488
|
type: "button",
|
|
463
489
|
className: "ckw-upvote",
|
|
464
490
|
"aria-pressed": post.voted,
|
|
465
|
-
"aria-label": `${post.voted ? "Remove your vote" : "Upvote"}. ${post.votes}
|
|
491
|
+
"aria-label": `${post.voted ? t("Remove your vote") : t("Upvote")}. ${votesWord(post.votes)}`,
|
|
466
492
|
onClick: () => onVote(post),
|
|
467
493
|
children: [
|
|
468
494
|
/* @__PURE__ */ jsx(ChevronUp, {}),
|
|
469
|
-
/* @__PURE__ */ jsx("span", { children: post.voted ? "Upvoted" : "Upvote" }),
|
|
495
|
+
/* @__PURE__ */ jsx("span", { children: post.voted ? t("Upvoted") : t("Upvote") }),
|
|
470
496
|
/* @__PURE__ */ jsx("b", { children: post.votes })
|
|
471
497
|
]
|
|
472
498
|
}
|
|
473
499
|
),
|
|
474
500
|
/* @__PURE__ */ jsxs("dl", { className: "ckw-facts", children: [
|
|
475
501
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
476
|
-
/* @__PURE__ */ jsx("dt", { children: "Status" }),
|
|
502
|
+
/* @__PURE__ */ jsx("dt", { children: t("Status") }),
|
|
477
503
|
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx(StatusPill, { status: post.status }) })
|
|
478
504
|
] }),
|
|
479
505
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
480
|
-
/* @__PURE__ */ jsx("dt", { children: "Type" }),
|
|
506
|
+
/* @__PURE__ */ jsx("dt", { children: t("Type") }),
|
|
481
507
|
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx(TypeChip, { board: post.board, boards }) })
|
|
482
508
|
] }),
|
|
483
509
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
484
|
-
/* @__PURE__ */ jsx("dt", { children: "Posted" }),
|
|
485
|
-
/* @__PURE__ */ jsx("dd", { children: new Date(post.createdAt).toLocaleDateString(
|
|
510
|
+
/* @__PURE__ */ jsx("dt", { children: t("Posted") }),
|
|
511
|
+
/* @__PURE__ */ jsx("dd", { children: new Date(post.createdAt).toLocaleDateString(currentLocale(), { month: "short", day: "numeric", year: "numeric" }) })
|
|
486
512
|
] })
|
|
487
513
|
] })
|
|
488
514
|
] })
|
|
489
515
|
] })
|
|
490
516
|
] });
|
|
491
517
|
};
|
|
492
|
-
var COLUMNS = [
|
|
493
|
-
{ status: "review", label: "Backlog", note: "Under consideration" },
|
|
494
|
-
{ status: "planned", label: "Next up", note: "Committed and queued" },
|
|
495
|
-
{ status: "progress", label: "In progress", note: "Actively being built" },
|
|
496
|
-
{ status: "shipped", label: "Done", note: "Recently shipped" }
|
|
518
|
+
var COLUMNS = () => [
|
|
519
|
+
{ status: "review", label: t("Backlog"), note: t("Under consideration") },
|
|
520
|
+
{ status: "planned", label: t("Next up"), note: t("Committed and queued") },
|
|
521
|
+
{ status: "progress", label: t("In progress"), note: t("Actively being built") },
|
|
522
|
+
{ status: "shipped", label: t("Done"), note: t("Recently shipped") }
|
|
497
523
|
];
|
|
498
524
|
var matchesQ = (q, ...texts) => {
|
|
499
|
-
const
|
|
500
|
-
return !
|
|
525
|
+
const q2 = q.trim().toLowerCase();
|
|
526
|
+
return !q2 || texts.some((x) => x.toLowerCase().includes(q2));
|
|
501
527
|
};
|
|
502
528
|
var RoadmapCard = ({
|
|
503
529
|
post,
|
|
@@ -511,7 +537,7 @@ var RoadmapCard = ({
|
|
|
511
537
|
/* @__PURE__ */ jsxs("div", { className: "ckw-card-foot", children: [
|
|
512
538
|
/* @__PURE__ */ jsxs("span", { className: "ckw-who", children: [
|
|
513
539
|
/* @__PURE__ */ jsx(Avatar, { name: post.author ?? "?", team: post.author === "Team" }),
|
|
514
|
-
/* @__PURE__ */ jsx("span", { children: post.author
|
|
540
|
+
/* @__PURE__ */ jsx("span", { children: post.author ? authorName(post.author) : "" })
|
|
515
541
|
] }),
|
|
516
542
|
/* @__PURE__ */ jsx(VoteButton, { post, onVote, small: true })
|
|
517
543
|
] })
|
|
@@ -541,10 +567,10 @@ var Roadmap = ({
|
|
|
541
567
|
const vote = (post) => voteRef(post, (r) => {
|
|
542
568
|
if (r) patch(post.id, (p) => ({ ...p, ...r }));
|
|
543
569
|
});
|
|
544
|
-
if (error) return /* @__PURE__ */ jsx(ErrorBar, { message: error, onRetry: () => setTick((
|
|
570
|
+
if (error) return /* @__PURE__ */ jsx(ErrorBar, { message: error, onRetry: () => setTick((t2) => t2 + 1) });
|
|
545
571
|
if (!data)
|
|
546
|
-
return /* @__PURE__ */ jsx("div", { className: "ckw-cols", "aria-hidden": "true", children: COLUMNS.map((c) => /* @__PURE__ */ jsx("div", { className: "ckw-col", children: /* @__PURE__ */ jsx(Skeleton, { rows: 2 }) }, c.status)) });
|
|
547
|
-
return /* @__PURE__ */ jsx("div", { className: "ckw-cols", children: COLUMNS.map((c) => {
|
|
572
|
+
return /* @__PURE__ */ jsx("div", { className: "ckw-cols", "aria-hidden": "true", children: COLUMNS().map((c) => /* @__PURE__ */ jsx("div", { className: "ckw-col", children: /* @__PURE__ */ jsx(Skeleton, { rows: 2 }) }, c.status)) });
|
|
573
|
+
return /* @__PURE__ */ jsx("div", { className: "ckw-cols", children: COLUMNS().map((c) => {
|
|
548
574
|
const cards = (data.columns[c.status] ?? []).filter((p) => matchesQ(q, p.title, p.body));
|
|
549
575
|
return /* @__PURE__ */ jsxs("section", { className: "ckw-col", "aria-label": c.label, children: [
|
|
550
576
|
/* @__PURE__ */ jsxs("header", { className: "ckw-col-head", children: [
|
|
@@ -555,7 +581,7 @@ var Roadmap = ({
|
|
|
555
581
|
] }),
|
|
556
582
|
/* @__PURE__ */ jsx("p", { children: c.note })
|
|
557
583
|
] }),
|
|
558
|
-
cards.length === 0 ? /* @__PURE__ */ jsx("p", { className: "ckw-col-empty", children: q ? "No match" : "Nothing here yet" }) : /* @__PURE__ */ jsx("ul", { className: "ckw-col-list", children: cards.map((p) => /* @__PURE__ */ jsx(RoadmapCard, { post: p, boards, onOpen, onVote: vote }, p.id)) })
|
|
584
|
+
cards.length === 0 ? /* @__PURE__ */ jsx("p", { className: "ckw-col-empty", children: q ? t("No match") : t("Nothing here yet") }) : /* @__PURE__ */ jsx("ul", { className: "ckw-col-list", children: cards.map((p) => /* @__PURE__ */ jsx(RoadmapCard, { post: p, boards, onOpen, onVote: vote }, p.id)) })
|
|
559
585
|
] }, c.status);
|
|
560
586
|
}) });
|
|
561
587
|
};
|
|
@@ -568,22 +594,22 @@ var Changelog = ({ api, q }) => {
|
|
|
568
594
|
api.changelog(ctl.signal).then((r) => (setEntries(r.entries), setError(""))).catch((e) => e.name !== "AbortError" && setError(e.message));
|
|
569
595
|
return () => ctl.abort();
|
|
570
596
|
}, [api, tick]);
|
|
571
|
-
if (error) return /* @__PURE__ */ jsx(ErrorBar, { message: error, onRetry: () => setTick((
|
|
597
|
+
if (error) return /* @__PURE__ */ jsx(ErrorBar, { message: error, onRetry: () => setTick((t2) => t2 + 1) });
|
|
572
598
|
if (!entries) return /* @__PURE__ */ jsx(Skeleton, {});
|
|
573
599
|
const shown = entries.filter((e) => matchesQ(q, e.title, e.body));
|
|
574
|
-
if (shown.length === 0) return /* @__PURE__ */ jsx("div", { className: "ckw-empty", children: q ? "No update matches your search." : "No updates published yet." });
|
|
600
|
+
if (shown.length === 0) return /* @__PURE__ */ jsx("div", { className: "ckw-empty", children: q ? t("No update matches your search.") : t("No updates published yet.") });
|
|
575
601
|
return /* @__PURE__ */ jsx("div", { className: "ckw-log", children: shown.map((e) => /* @__PURE__ */ jsxs("article", { className: "ckw-entry", children: [
|
|
576
|
-
/* @__PURE__ */ jsx("time", { dateTime: e.publishedAt, children: new Date(e.publishedAt).toLocaleDateString(
|
|
602
|
+
/* @__PURE__ */ jsx("time", { dateTime: e.publishedAt, children: new Date(e.publishedAt).toLocaleDateString(currentLocale(), { month: "long", day: "numeric", year: "numeric" }) }),
|
|
577
603
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
578
604
|
/* @__PURE__ */ jsx("h3", { children: e.title }),
|
|
579
605
|
/* @__PURE__ */ jsx("p", { children: e.body })
|
|
580
606
|
] })
|
|
581
607
|
] }, e.id)) });
|
|
582
608
|
};
|
|
583
|
-
var TABS = [
|
|
584
|
-
["requests", "Feedback"],
|
|
585
|
-
["roadmap", "Roadmap"],
|
|
586
|
-
["changelog", "Changelog"]
|
|
609
|
+
var TABS = () => [
|
|
610
|
+
["requests", t("Feedback")],
|
|
611
|
+
["roadmap", t("Roadmap")],
|
|
612
|
+
["changelog", t("Changelog")]
|
|
587
613
|
];
|
|
588
614
|
var readUrl = () => {
|
|
589
615
|
const p = new URLSearchParams(window.location.search);
|
|
@@ -604,8 +630,8 @@ var THEME_KEY = "ckw-theme";
|
|
|
604
630
|
var systemDark = () => typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
605
631
|
var EmptyGlyph = () => /* @__PURE__ */ jsx("svg", { className: "ckw-empty-icon", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M12 2.5c-5.25 0-9.5 3.73-9.5 8.33 0 2.47 1.23 4.69 3.18 6.21-.17 1.33-.73 2.6-1.63 3.63a.6.6 0 0 0 .5 1c2.13-.12 4-.86 5.38-1.92.67.13 1.36.2 2.07.2 5.25 0 9.5-3.73 9.5-8.33S17.25 2.5 12 2.5Zm.9 4.2-.6 3.3h2.2a.5.5 0 0 1 .4.8l-3.5 4.5a.4.4 0 0 1-.7-.35l.6-3.15H9.1a.5.5 0 0 1-.4-.8l3.5-4.65a.4.4 0 0 1 .7.35Z" }) });
|
|
606
632
|
var FeedbackBoard = ({
|
|
607
|
-
title = "Feedback",
|
|
608
|
-
subtitle = "Tell us what to build next and vote on what matters to you.",
|
|
633
|
+
title = t("Feedback"),
|
|
634
|
+
subtitle = t("Tell us what to build next and vote on what matters to you."),
|
|
609
635
|
theme,
|
|
610
636
|
accent,
|
|
611
637
|
header = true,
|
|
@@ -628,11 +654,19 @@ var FeedbackBoard = ({
|
|
|
628
654
|
const list = useFeedbackList(identity.api, { board, sort, q: tab === "requests" ? q : "" });
|
|
629
655
|
const { posts, setPosts, vote } = list;
|
|
630
656
|
const searchRef = useRef(null);
|
|
657
|
+
const [plan, setPlan] = useState(null);
|
|
658
|
+
useEffect(() => {
|
|
659
|
+
if (!header) return;
|
|
660
|
+
const ctl = new AbortController();
|
|
661
|
+
identity.api.roadmap(ctl.signal).then(setPlan).catch(() => {
|
|
662
|
+
});
|
|
663
|
+
return () => ctl.abort();
|
|
664
|
+
}, [header, identity.api]);
|
|
631
665
|
useEffect(() => {
|
|
632
666
|
if (!header) return;
|
|
633
667
|
try {
|
|
634
|
-
const
|
|
635
|
-
if (
|
|
668
|
+
const t2 = window.localStorage.getItem(THEME_KEY);
|
|
669
|
+
if (t2 === "light" || t2 === "dark") setMode(t2);
|
|
636
670
|
} catch {
|
|
637
671
|
}
|
|
638
672
|
}, [header]);
|
|
@@ -693,15 +727,16 @@ var FeedbackBoard = ({
|
|
|
693
727
|
}).catch((e) => {
|
|
694
728
|
setOpened((o) => o && o.id === p.id ? { ...o, voted: p.voted, votes: p.votes } : o);
|
|
695
729
|
done?.({ voted: p.voted, votes: p.votes });
|
|
696
|
-
list.setError(
|
|
730
|
+
list.setError(`${t("Your vote was not saved.")} ${e.message}`);
|
|
697
731
|
});
|
|
698
732
|
});
|
|
699
733
|
const onTabKey = (e) => {
|
|
700
|
-
const
|
|
734
|
+
const tabs = TABS();
|
|
735
|
+
const i = tabs.findIndex(([k]) => k === tab);
|
|
701
736
|
const n = e.key === "ArrowRight" ? i + 1 : e.key === "ArrowLeft" ? i - 1 : null;
|
|
702
737
|
if (n === null) return;
|
|
703
738
|
e.preventDefault();
|
|
704
|
-
go(
|
|
739
|
+
go(tabs[(n + tabs.length) % tabs.length][0]);
|
|
705
740
|
};
|
|
706
741
|
const product = list.product;
|
|
707
742
|
const abs = (u) => u ? u.startsWith("/") ? `${host}${u}` : u : null;
|
|
@@ -710,8 +745,8 @@ var FeedbackBoard = ({
|
|
|
710
745
|
const logo = marks[failed] ?? null;
|
|
711
746
|
const name = product?.name ?? title;
|
|
712
747
|
const newPost = () => (setThanks(false), setCreating(true));
|
|
713
|
-
const searchLabel = tab === "roadmap" ? "Search roadmap" : tab === "changelog" ? "Search updates" : "Search requests";
|
|
714
|
-
return /* @__PURE__ */ jsxs(Root, { theme: header ? dark ? "dark" : "light" : theme, accent, className: `ckw-board${fullPage ? "ckw-full" : ""}`, children: [
|
|
748
|
+
const searchLabel = tab === "roadmap" ? t("Search roadmap") : tab === "changelog" ? t("Search updates") : t("Search requests");
|
|
749
|
+
return /* @__PURE__ */ jsxs(Root, { theme: header ? dark ? "dark" : "light" : theme, accent, className: `ckw-board${fullPage ? " ckw-full" : ""}`, children: [
|
|
715
750
|
header ? /* @__PURE__ */ jsx("header", { className: "ckw-top", children: /* @__PURE__ */ jsxs("div", { className: "ckw-top-row", children: [
|
|
716
751
|
/* @__PURE__ */ jsxs("button", { type: "button", className: "ckw-brand", onClick: () => go("requests"), children: [
|
|
717
752
|
logo ? (
|
|
@@ -720,7 +755,7 @@ var FeedbackBoard = ({
|
|
|
720
755
|
) : /* @__PURE__ */ jsx("span", { className: "ckw-brand-mark", "aria-hidden": "true", children: name.slice(0, 1).toUpperCase() }),
|
|
721
756
|
/* @__PURE__ */ jsx("span", { children: name })
|
|
722
757
|
] }),
|
|
723
|
-
/* @__PURE__ */ jsx("nav", { className: "ckw-nav", role: "tablist", "aria-label": "Board sections", onKeyDown: onTabKey, children: TABS.map(([k, label]) => /* @__PURE__ */ jsx(
|
|
758
|
+
/* @__PURE__ */ jsx("nav", { className: "ckw-nav", role: "tablist", "aria-label": t("Board sections"), onKeyDown: onTabKey, children: TABS().map(([k, label]) => /* @__PURE__ */ jsx(
|
|
724
759
|
"button",
|
|
725
760
|
{
|
|
726
761
|
type: "button",
|
|
@@ -756,7 +791,7 @@ var FeedbackBoard = ({
|
|
|
756
791
|
type: "search",
|
|
757
792
|
className: "ckw-search-input",
|
|
758
793
|
"aria-label": searchLabel,
|
|
759
|
-
placeholder: "Search\u2026",
|
|
794
|
+
placeholder: t("Search\u2026"),
|
|
760
795
|
value: q,
|
|
761
796
|
onChange: (e) => {
|
|
762
797
|
setQ(e.target.value);
|
|
@@ -773,14 +808,14 @@ var FeedbackBoard = ({
|
|
|
773
808
|
type: "button",
|
|
774
809
|
className: "ckw-icon-btn",
|
|
775
810
|
onClick: flipTheme,
|
|
776
|
-
"aria-label": dark ? "Switch to light mode" : "Switch to dark mode",
|
|
811
|
+
"aria-label": dark ? t("Switch to light mode") : t("Switch to dark mode"),
|
|
777
812
|
children: dark ? /* @__PURE__ */ jsx(Sun, {}) : /* @__PURE__ */ jsx(Moon, {})
|
|
778
813
|
}
|
|
779
814
|
),
|
|
780
|
-
/* @__PURE__ */ jsxs("button", { type: "button", className: "ckw-btn ckw-btn-primary ckw-submit", "aria-label": "Submit feedback", onClick: newPost, children: [
|
|
815
|
+
/* @__PURE__ */ jsxs("button", { type: "button", className: "ckw-btn ckw-btn-primary ckw-submit", "aria-label": t("Submit feedback"), onClick: newPost, children: [
|
|
781
816
|
/* @__PURE__ */ jsx(Plus, {}),
|
|
782
817
|
" ",
|
|
783
|
-
/* @__PURE__ */ jsx("span", { children: "Submit feedback" })
|
|
818
|
+
/* @__PURE__ */ jsx("span", { children: t("Submit feedback") })
|
|
784
819
|
] })
|
|
785
820
|
] })
|
|
786
821
|
] }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -791,10 +826,11 @@ var FeedbackBoard = ({
|
|
|
791
826
|
] }),
|
|
792
827
|
/* @__PURE__ */ jsxs("button", { type: "button", className: "ckw-btn ckw-btn-primary", onClick: newPost, children: [
|
|
793
828
|
/* @__PURE__ */ jsx(Plus, {}),
|
|
794
|
-
"
|
|
829
|
+
" ",
|
|
830
|
+
t("Request a feature")
|
|
795
831
|
] })
|
|
796
832
|
] }),
|
|
797
|
-
/* @__PURE__ */ jsx("div", { className: "ckw-tabs", role: "tablist", "aria-label": "Feedback sections", onKeyDown: onTabKey, children: TABS.map(([k, label]) => /* @__PURE__ */ jsx(
|
|
833
|
+
/* @__PURE__ */ jsx("div", { className: "ckw-tabs", role: "tablist", "aria-label": t("Feedback sections"), onKeyDown: onTabKey, children: TABS().map(([k, label]) => /* @__PURE__ */ jsx(
|
|
798
834
|
"button",
|
|
799
835
|
{
|
|
800
836
|
type: "button",
|
|
@@ -804,7 +840,7 @@ var FeedbackBoard = ({
|
|
|
804
840
|
tabIndex: tab === k ? 0 : -1,
|
|
805
841
|
className: "ckw-tab",
|
|
806
842
|
onClick: () => go(k),
|
|
807
|
-
children: k === "requests" ? "Requests" : label
|
|
843
|
+
children: k === "requests" ? t("Requests") : label
|
|
808
844
|
},
|
|
809
845
|
k
|
|
810
846
|
)) }),
|
|
@@ -823,12 +859,12 @@ var FeedbackBoard = ({
|
|
|
823
859
|
] }),
|
|
824
860
|
/* @__PURE__ */ jsxs("div", { className: "ckw-body-wrap", role: "tabpanel", "aria-labelledby": `ckw-tab-${tab}`, children: [
|
|
825
861
|
header && !current && /* @__PURE__ */ jsxs("div", { className: "ckw-intro", children: [
|
|
826
|
-
/* @__PURE__ */ jsx("h1", { children: tab === "roadmap" ? "Roadmap" : tab === "changelog" ? "Changelog" : "Feedback" }),
|
|
827
|
-
/* @__PURE__ */ jsx("p", { children: tab === "roadmap" ? "What we are considering, building next and shipped." : tab === "changelog" ? "New and improved, newest first." : subtitle })
|
|
862
|
+
/* @__PURE__ */ jsx("h1", { children: tab === "roadmap" ? t("Roadmap") : tab === "changelog" ? t("Changelog") : t("Feedback") }),
|
|
863
|
+
/* @__PURE__ */ jsx("p", { children: tab === "roadmap" ? t("What we are considering, building next and shipped.") : tab === "changelog" ? t("New and improved, newest first.") : subtitle })
|
|
828
864
|
] }),
|
|
829
865
|
thanks && !current && /* @__PURE__ */ jsxs("div", { className: "ckw-note", role: "status", children: [
|
|
830
|
-
"Thanks, your request is in. You can follow it here.",
|
|
831
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-icon-btn", "aria-label": "Dismiss", onClick: () => setThanks(false), children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
866
|
+
t("Thanks, your request is in. You can follow it here."),
|
|
867
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-icon-btn", "aria-label": t("Dismiss"), onClick: () => setThanks(false), children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
832
868
|
] }),
|
|
833
869
|
list.error && /* @__PURE__ */ jsx(ErrorBar, { message: list.error, onRetry: tab === "requests" && !current ? list.reload : void 0, onClose: () => list.setError("") }),
|
|
834
870
|
current ? /* @__PURE__ */ jsx(
|
|
@@ -837,7 +873,7 @@ var FeedbackBoard = ({
|
|
|
837
873
|
post: current,
|
|
838
874
|
boards: list.boards,
|
|
839
875
|
identity,
|
|
840
|
-
backLabel: tab === "roadmap" ? "Roadmap" : "All requests",
|
|
876
|
+
backLabel: tab === "roadmap" ? t("Roadmap") : t("All requests"),
|
|
841
877
|
onBack: () => go(tab),
|
|
842
878
|
onVote: (p) => voteAny(p)
|
|
843
879
|
}
|
|
@@ -852,11 +888,13 @@ var FeedbackBoard = ({
|
|
|
852
888
|
q,
|
|
853
889
|
onOpen: (p) => go("requests", p),
|
|
854
890
|
onVote: (p) => voteAny(p),
|
|
855
|
-
onNew: newPost
|
|
891
|
+
onNew: newPost,
|
|
892
|
+
roadmap: plan,
|
|
893
|
+
onRoadmap: () => go("roadmap")
|
|
856
894
|
}
|
|
857
895
|
) : tab === "roadmap" ? /* @__PURE__ */ jsx(Roadmap, { api: identity.api, boards: list.boards, q, onOpen: (p) => go("roadmap", p), voteRef: (p, done) => voteAny(p, done) }) : /* @__PURE__ */ jsx(Changelog, { api: identity.api, q })
|
|
858
896
|
] }),
|
|
859
|
-
creating && /* @__PURE__ */ jsx(Modal, { title: "Submit feedback", onClose: () => setCreating(false), children: /* @__PURE__ */ jsx(
|
|
897
|
+
creating && /* @__PURE__ */ jsx(Modal, { title: t("Submit feedback"), onClose: () => setCreating(false), children: /* @__PURE__ */ jsx(
|
|
860
898
|
SubmitForm,
|
|
861
899
|
{
|
|
862
900
|
bare: true,
|
|
@@ -875,11 +913,14 @@ var FeedbackBoard = ({
|
|
|
875
913
|
) }),
|
|
876
914
|
/* @__PURE__ */ jsx(IdentityDialog, { identity }),
|
|
877
915
|
identity.known && !identity.fromApp && header && /* @__PURE__ */ jsxs("p", { className: "ckw-foot", children: [
|
|
878
|
-
"Posting as ",
|
|
879
|
-
identity.name,
|
|
880
|
-
".",
|
|
916
|
+
tf("Posting as {name}.", { name: identity.name }),
|
|
881
917
|
" ",
|
|
882
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-linkish", onClick: identity.forget, children: "Not you?" })
|
|
918
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-linkish", onClick: identity.forget, children: t("Not you?") })
|
|
919
|
+
] }),
|
|
920
|
+
header && /* @__PURE__ */ jsxs("a", { className: "ckw-powered", href: "https://mrrocket.dev/?utm_source=board&utm_medium=powered-by", target: "_blank", rel: "noreferrer", children: [
|
|
921
|
+
t("Powered by {brand}").split("{brand}")[0],
|
|
922
|
+
/* @__PURE__ */ jsx("b", { children: "MRRocket" }),
|
|
923
|
+
t("Powered by {brand}").split("{brand}")[1]
|
|
883
924
|
] })
|
|
884
925
|
] });
|
|
885
926
|
};
|
|
@@ -899,12 +940,12 @@ var WidgetPanel = ({ boardUrl, onClose }) => {
|
|
|
899
940
|
const vote = (p) => identity.need((as) => list.vote(p, as));
|
|
900
941
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
901
942
|
/* @__PURE__ */ jsxs("div", { className: "ckw-pop-head", children: [
|
|
902
|
-
/* @__PURE__ */ jsx("span", { children: suggesting ? "Suggest something" : "Top requests" }),
|
|
903
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: onClose, "aria-label": "Close feedback", children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
943
|
+
/* @__PURE__ */ jsx("span", { children: suggesting ? t("Suggest something") : t("Top requests") }),
|
|
944
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: onClose, "aria-label": t("Close feedback"), children: /* @__PURE__ */ jsx(Cross, {}) })
|
|
904
945
|
] }),
|
|
905
946
|
/* @__PURE__ */ jsxs("div", { className: "ckw-pop-body", children: [
|
|
906
947
|
list.error && /* @__PURE__ */ jsx(ErrorBar, { message: list.error, onClose: () => list.setError("") }),
|
|
907
|
-
identity.asking ? /* @__PURE__ */ jsx(WidgetIdentity, { identity }) : thanks ? /* @__PURE__ */ jsx("div", { className: "ckw-empty", role: "status", children: "Thanks, your request is in." }) : suggesting ? /* @__PURE__ */ jsx(
|
|
948
|
+
identity.asking ? /* @__PURE__ */ jsx(WidgetIdentity, { identity }) : thanks ? /* @__PURE__ */ jsx("div", { className: "ckw-empty", role: "status", children: t("Thanks, your request is in.") }) : suggesting ? /* @__PURE__ */ jsx(
|
|
908
949
|
SubmitForm,
|
|
909
950
|
{
|
|
910
951
|
compact: true,
|
|
@@ -919,7 +960,7 @@ var WidgetPanel = ({ boardUrl, onClose }) => {
|
|
|
919
960
|
setThanks(true);
|
|
920
961
|
}
|
|
921
962
|
}
|
|
922
|
-
) : list.loading && posts.length === 0 ? /* @__PURE__ */ jsx(Skeleton, {}) : posts.length === 0 && !list.error ? /* @__PURE__ */ jsx("div", { className: "ckw-empty", children: "No requests yet. Suggest the first one." }) : /* @__PURE__ */ jsx("ul", { className: "ckw-list", "aria-live": "polite", children: posts.slice(0, 5).map((p) => /* @__PURE__ */ jsxs("li", { className: "ckw-row", children: [
|
|
963
|
+
) : list.loading && posts.length === 0 ? /* @__PURE__ */ jsx(Skeleton, {}) : posts.length === 0 && !list.error ? /* @__PURE__ */ jsx("div", { className: "ckw-empty", children: t("No requests yet. Suggest the first one.") }) : /* @__PURE__ */ jsx("ul", { className: "ckw-list", "aria-live": "polite", children: posts.slice(0, 5).map((p) => /* @__PURE__ */ jsxs("li", { className: "ckw-row", children: [
|
|
923
964
|
/* @__PURE__ */ jsx(VoteButton, { post: p, onVote: vote }),
|
|
924
965
|
/* @__PURE__ */ jsxs("div", { className: "ckw-main", children: [
|
|
925
966
|
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600, overflowWrap: "anywhere" }, children: p.title }),
|
|
@@ -928,12 +969,13 @@ var WidgetPanel = ({ boardUrl, onClose }) => {
|
|
|
928
969
|
] }, p.id)) })
|
|
929
970
|
] }),
|
|
930
971
|
/* @__PURE__ */ jsxs("div", { className: "ckw-pop-foot", children: [
|
|
931
|
-
boardUrl ? /* @__PURE__ */ jsx("a", { href: boardUrl, children: "See all" }) : /* @__PURE__ */ jsx("span", {}),
|
|
972
|
+
boardUrl ? /* @__PURE__ */ jsx("a", { href: boardUrl, children: t("See all") }) : /* @__PURE__ */ jsx("span", {}),
|
|
932
973
|
!suggesting && !thanks && !identity.asking && /* @__PURE__ */ jsxs("button", { type: "button", className: "ckw-btn ckw-btn-primary", onClick: () => setSuggesting(true), children: [
|
|
933
974
|
/* @__PURE__ */ jsx(Plus, {}),
|
|
934
|
-
"
|
|
975
|
+
" ",
|
|
976
|
+
t("Suggest something")
|
|
935
977
|
] }),
|
|
936
|
-
thanks && /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn", onClick: () => setThanks(false), children: "Back" })
|
|
978
|
+
thanks && /* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn", onClick: () => setThanks(false), children: t("Back") })
|
|
937
979
|
] })
|
|
938
980
|
] });
|
|
939
981
|
};
|
|
@@ -956,14 +998,14 @@ var WidgetIdentity = ({ identity }) => {
|
|
|
956
998
|
children: [
|
|
957
999
|
/* @__PURE__ */ jsx(IdentityFields, { name, email, setName, setEmail }),
|
|
958
1000
|
/* @__PURE__ */ jsxs("div", { className: "ckw-actions", children: [
|
|
959
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: identity.cancel, children: "Cancel" }),
|
|
960
|
-
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: !ok, children: "Continue" })
|
|
1001
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ckw-btn ckw-btn-ghost", onClick: identity.cancel, children: t("Cancel") }),
|
|
1002
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "ckw-btn ckw-btn-primary", disabled: !ok, children: t("Continue") })
|
|
961
1003
|
] })
|
|
962
1004
|
]
|
|
963
1005
|
}
|
|
964
1006
|
);
|
|
965
1007
|
};
|
|
966
|
-
var FeedbackWidget = ({ position = "bottom-right", label = "Feedback", boardUrl, theme, accent }) => {
|
|
1008
|
+
var FeedbackWidget = ({ position = "bottom-right", label = t("Feedback"), boardUrl, theme, accent }) => {
|
|
967
1009
|
const [open, setOpen] = useState(false);
|
|
968
1010
|
const fab = useRef(null);
|
|
969
1011
|
const pop = useRef(null);
|
|
@@ -1018,7 +1060,7 @@ var FeedbackWidget = ({ position = "bottom-right", label = "Feedback", boardUrl,
|
|
|
1018
1060
|
]
|
|
1019
1061
|
}
|
|
1020
1062
|
),
|
|
1021
|
-
open && /* @__PURE__ */ jsx("div", { ref: pop, className: "ckw-pop", "data-pos": position, role: "dialog", "aria-label": "Feedback", onKeyDown: trap, children: /* @__PURE__ */ jsx(WidgetPanel, { boardUrl, onClose: close }) })
|
|
1063
|
+
open && /* @__PURE__ */ jsx("div", { ref: pop, className: "ckw-pop", "data-pos": position, role: "dialog", "aria-label": t("Feedback"), onKeyDown: trap, children: /* @__PURE__ */ jsx(WidgetPanel, { boardUrl, onClose: close }) })
|
|
1022
1064
|
] });
|
|
1023
1065
|
};
|
|
1024
1066
|
export {
|