@mhosaic/feedback 0.32.0 → 0.33.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/dist/{chunk-YNDBZR37.mjs → chunk-RR6UB75B.mjs} +441 -362
- package/dist/chunk-RR6UB75B.mjs.map +1 -0
- package/dist/{chunk-IP4Y5EZE.mjs → chunk-WROPP3IB.mjs} +17 -1
- package/dist/chunk-WROPP3IB.mjs.map +1 -0
- package/dist/embed.min.js +5 -5
- package/dist/embed.min.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/loader/react.mjs +1 -1
- package/dist/loader.min.js +1 -1
- package/dist/loader.min.js.map +1 -1
- package/dist/loader.mjs +1 -1
- package/dist/react.mjs +1 -1
- package/dist/widget.min.js +6 -6
- package/dist/widget.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-IP4Y5EZE.mjs.map +0 -1
- package/dist/chunk-YNDBZR37.mjs.map +0 -1
|
@@ -145,6 +145,32 @@ function createApiClient(options) {
|
|
|
145
145
|
if (response.status === 404) return [];
|
|
146
146
|
return readJsonArray(response, "listMine");
|
|
147
147
|
}
|
|
148
|
+
async function diagnose(opts) {
|
|
149
|
+
const onLine = opts?.onLine ?? (typeof navigator !== "undefined" ? navigator.onLine : true);
|
|
150
|
+
if (onLine === false) return "offline";
|
|
151
|
+
const probeUrl = `${endpoint}/api/feedback/v1/widget-manifest/?pk=${encodeURIComponent(options.apiKey)}`;
|
|
152
|
+
let simple;
|
|
153
|
+
try {
|
|
154
|
+
simple = await fetcher(probeUrl, { method: "GET", redirect: "manual" });
|
|
155
|
+
} catch {
|
|
156
|
+
return "blocked";
|
|
157
|
+
}
|
|
158
|
+
if (simple.type === "opaqueredirect" || simple.status >= 300 && simple.status < 400) {
|
|
159
|
+
return "intercepted";
|
|
160
|
+
}
|
|
161
|
+
let authed;
|
|
162
|
+
try {
|
|
163
|
+
authed = await fetcher(probeUrl, {
|
|
164
|
+
method: "GET",
|
|
165
|
+
headers: { Authorization: `Bearer ${options.apiKey}` }
|
|
166
|
+
});
|
|
167
|
+
} catch {
|
|
168
|
+
return "preflight";
|
|
169
|
+
}
|
|
170
|
+
if (authed.status === 401 || authed.status === 403) return "key";
|
|
171
|
+
if (authed.status === 429) return "throttle";
|
|
172
|
+
return "healthy";
|
|
173
|
+
}
|
|
148
174
|
async function listChangelog(externalId) {
|
|
149
175
|
const response = await fetcher(
|
|
150
176
|
`${endpoint}/api/feedback/v1/reports/widget/changelog/`,
|
|
@@ -330,6 +356,14 @@ function createApiClient(options) {
|
|
|
330
356
|
checkVisibility,
|
|
331
357
|
listMine,
|
|
332
358
|
listChangelog,
|
|
359
|
+
diagnose,
|
|
360
|
+
endpointHost: (() => {
|
|
361
|
+
try {
|
|
362
|
+
return new URL(endpoint).host;
|
|
363
|
+
} catch {
|
|
364
|
+
return endpoint;
|
|
365
|
+
}
|
|
366
|
+
})(),
|
|
333
367
|
getReport,
|
|
334
368
|
getReportBySeq,
|
|
335
369
|
addComment,
|
|
@@ -739,6 +773,15 @@ var DEFAULT_STRINGS = {
|
|
|
739
773
|
"mine.empty.title": "No reports yet",
|
|
740
774
|
"mine.empty.body": "Once you send feedback you can follow the thread here.",
|
|
741
775
|
"mine.refresh": "Refresh",
|
|
776
|
+
"diag.run": "Diagnose",
|
|
777
|
+
"diag.running": "Checking the connection\u2026",
|
|
778
|
+
"diag.offline": "You appear to be offline. Reconnect and retry.",
|
|
779
|
+
"diag.blocked": "The feedback service is unreachable from this network. A firewall or proxy is blocking it \u2014 ask IT to allow {host}.",
|
|
780
|
+
"diag.intercepted": "Your corporate network (SSL-inspection proxy) is intercepting widget traffic. Ask IT to add {host} to the inspection bypass list.",
|
|
781
|
+
"diag.preflight": "A network proxy is blocking the widget\u2019s secure requests (CORS preflight). Ask IT to allow {host}.",
|
|
782
|
+
"diag.key": "The widget\u2019s access key was rejected. Contact the site team.",
|
|
783
|
+
"diag.throttle": "Too many requests right now \u2014 wait a moment and retry.",
|
|
784
|
+
"diag.healthy": "The service is reachable \u2014 this looks like a temporary hiccup. Retry.",
|
|
742
785
|
"mine.loading": "Loading\u2026",
|
|
743
786
|
"mine.error": "Could not load your reports.",
|
|
744
787
|
"mine.jump.placeholder": "#",
|
|
@@ -926,6 +969,15 @@ var FRENCH_STRINGS = {
|
|
|
926
969
|
"mine.empty.title": "Aucun rapport",
|
|
927
970
|
"mine.empty.body": "Apr\xE8s votre premier envoi vous pourrez suivre la conversation ici.",
|
|
928
971
|
"mine.refresh": "Actualiser",
|
|
972
|
+
"diag.run": "Diagnostiquer",
|
|
973
|
+
"diag.running": "V\xE9rification de la connexion\u2026",
|
|
974
|
+
"diag.offline": "Vous semblez hors ligne. Reconnectez-vous puis r\xE9essayez.",
|
|
975
|
+
"diag.blocked": "Le service de feedback est injoignable depuis ce r\xE9seau. Un pare-feu ou proxy le bloque \u2014 demandez \xE0 votre TI d\u2019autoriser {host}.",
|
|
976
|
+
"diag.intercepted": "Votre r\xE9seau d\u2019entreprise (inspection SSL) intercepte le trafic du widget. Demandez \xE0 votre TI d\u2019ajouter {host} \xE0 la liste d\u2019exclusion.",
|
|
977
|
+
"diag.preflight": "Un proxy r\xE9seau bloque les requ\xEAtes s\xE9curis\xE9es du widget (pr\xE9flight CORS). Demandez \xE0 votre TI d\u2019autoriser {host}.",
|
|
978
|
+
"diag.key": "La cl\xE9 d\u2019acc\xE8s du widget a \xE9t\xE9 refus\xE9e. Contactez l\u2019\xE9quipe du site.",
|
|
979
|
+
"diag.throttle": "Trop de requ\xEAtes pour le moment \u2014 patientez puis r\xE9essayez.",
|
|
980
|
+
"diag.healthy": "Le service est joignable \u2014 le probl\xE8me semble passager. R\xE9essayez.",
|
|
929
981
|
"mine.loading": "Chargement\u2026",
|
|
930
982
|
"mine.error": "Impossible de charger vos rapports.",
|
|
931
983
|
"mine.jump.placeholder": "#",
|
|
@@ -1017,7 +1069,7 @@ function resolveStrings(overrides, options = {}) {
|
|
|
1017
1069
|
|
|
1018
1070
|
// src/widget/mount.tsx
|
|
1019
1071
|
import { h, render } from "preact";
|
|
1020
|
-
import { useCallback as useCallback2, useEffect as useEffect10, useRef as useRef7, useState as
|
|
1072
|
+
import { useCallback as useCallback2, useEffect as useEffect10, useRef as useRef7, useState as useState10 } from "preact/hooks";
|
|
1021
1073
|
|
|
1022
1074
|
// src/widget/currentPage.ts
|
|
1023
1075
|
function currentPagePath(opts) {
|
|
@@ -1050,7 +1102,30 @@ function onLocationChange(cb) {
|
|
|
1050
1102
|
}
|
|
1051
1103
|
|
|
1052
1104
|
// src/widget/BoardView.tsx
|
|
1053
|
-
import { useEffect as useEffect2, useMemo, useState as
|
|
1105
|
+
import { useEffect as useEffect2, useMemo, useState as useState3 } from "preact/hooks";
|
|
1106
|
+
|
|
1107
|
+
// src/widget/DiagnosticHint.tsx
|
|
1108
|
+
import { useState } from "preact/hooks";
|
|
1109
|
+
import { jsx } from "preact/jsx-runtime";
|
|
1110
|
+
function DiagnosticHint({ api, strings, host }) {
|
|
1111
|
+
const [state, setState] = useState("idle");
|
|
1112
|
+
const run = async () => {
|
|
1113
|
+
setState("running");
|
|
1114
|
+
try {
|
|
1115
|
+
setState(await api.diagnose());
|
|
1116
|
+
} catch {
|
|
1117
|
+
setState("blocked");
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
1120
|
+
if (state === "idle") {
|
|
1121
|
+
return /* @__PURE__ */ jsx("button", { type: "button", class: "btn diag-btn", onClick: () => void run(), children: strings["diag.run"] });
|
|
1122
|
+
}
|
|
1123
|
+
if (state === "running") {
|
|
1124
|
+
return /* @__PURE__ */ jsx("div", { class: "diag-result", children: strings["diag.running"] });
|
|
1125
|
+
}
|
|
1126
|
+
const key = `diag.${state}`;
|
|
1127
|
+
return /* @__PURE__ */ jsx("div", { class: "diag-result", children: (strings[key] ?? state).replace("{host}", host) });
|
|
1128
|
+
}
|
|
1054
1129
|
|
|
1055
1130
|
// src/widget/boardCache.ts
|
|
1056
1131
|
var TTL_MS = 6e4;
|
|
@@ -1142,7 +1217,7 @@ function rateLimitMessage(err, strings) {
|
|
|
1142
1217
|
}
|
|
1143
1218
|
|
|
1144
1219
|
// src/widget/ReportDetailView.tsx
|
|
1145
|
-
import { useEffect, useRef, useState } from "preact/hooks";
|
|
1220
|
+
import { useEffect, useRef, useState as useState2 } from "preact/hooks";
|
|
1146
1221
|
|
|
1147
1222
|
// src/widget/linkifySeq.tsx
|
|
1148
1223
|
import { jsxs } from "preact/jsx-runtime";
|
|
@@ -1179,7 +1254,7 @@ function linkifySeq(text, onOpenSeq) {
|
|
|
1179
1254
|
}
|
|
1180
1255
|
|
|
1181
1256
|
// src/widget/CommentBubble.tsx
|
|
1182
|
-
import { jsx, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
1257
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
1183
1258
|
function CommentBubble({ comment, strings, onOpenSeq, stableUrl }) {
|
|
1184
1259
|
const isMine = comment.is_mine;
|
|
1185
1260
|
const isAgent = !isMine && comment.author_source === "mcp";
|
|
@@ -1189,23 +1264,23 @@ function CommentBubble({ comment, strings, onOpenSeq, stableUrl }) {
|
|
|
1189
1264
|
const label = comment.author_label || strings[labelKey];
|
|
1190
1265
|
const images = (comment.attachments ?? []).filter((a) => a.url);
|
|
1191
1266
|
return /* @__PURE__ */ jsxs2("div", { class: `comment-bubble ${isMine ? "is-mine" : "is-other"}`, children: [
|
|
1192
|
-
!isMine && label && /* @__PURE__ */
|
|
1193
|
-
comment.body && /* @__PURE__ */
|
|
1194
|
-
images.length > 0 && /* @__PURE__ */
|
|
1267
|
+
!isMine && label && /* @__PURE__ */ jsx2("div", { class: `comment-author comment-author--${variant}`, children: label }),
|
|
1268
|
+
comment.body && /* @__PURE__ */ jsx2("div", { class: "comment-body", children: linkifySeq(comment.body, onOpenSeq) }),
|
|
1269
|
+
images.length > 0 && /* @__PURE__ */ jsx2("div", { class: "comment-attachments", children: images.map((a) => {
|
|
1195
1270
|
const src = stableUrl ? stableUrl(`att:${a.id}`, a.url) : a.url;
|
|
1196
|
-
return /* @__PURE__ */
|
|
1271
|
+
return /* @__PURE__ */ jsx2(
|
|
1197
1272
|
"a",
|
|
1198
1273
|
{
|
|
1199
1274
|
class: "comment-attachment",
|
|
1200
1275
|
href: src,
|
|
1201
1276
|
target: "_blank",
|
|
1202
1277
|
rel: "noopener noreferrer",
|
|
1203
|
-
children: /* @__PURE__ */
|
|
1278
|
+
children: /* @__PURE__ */ jsx2("img", { src, alt: strings["detail.attachment_alt"], loading: "lazy" })
|
|
1204
1279
|
},
|
|
1205
1280
|
a.id
|
|
1206
1281
|
);
|
|
1207
1282
|
}) }),
|
|
1208
|
-
/* @__PURE__ */
|
|
1283
|
+
/* @__PURE__ */ jsx2("div", { class: "comment-time", children: formatTime(comment.created_at) })
|
|
1209
1284
|
] });
|
|
1210
1285
|
}
|
|
1211
1286
|
function formatTime(iso) {
|
|
@@ -1260,7 +1335,7 @@ function safeExternalHref(url) {
|
|
|
1260
1335
|
}
|
|
1261
1336
|
|
|
1262
1337
|
// src/widget/ReportDetailView.tsx
|
|
1263
|
-
import { Fragment, jsx as
|
|
1338
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
1264
1339
|
var POLL_MS = 3e4;
|
|
1265
1340
|
function ReportDetailView({
|
|
1266
1341
|
api,
|
|
@@ -1274,23 +1349,23 @@ function ReportDetailView({
|
|
|
1274
1349
|
buildPermalink,
|
|
1275
1350
|
seed
|
|
1276
1351
|
}) {
|
|
1277
|
-
const [detail, setDetail] =
|
|
1278
|
-
const [error, setError] =
|
|
1279
|
-
const [copied, setCopied] =
|
|
1280
|
-
const [editing, setEditing] =
|
|
1281
|
-
const [editBody, setEditBody] =
|
|
1282
|
-
const [savingEdit, setSavingEdit] =
|
|
1283
|
-
const [editError, setEditError] =
|
|
1284
|
-
const [composeBody, setComposeBody] =
|
|
1285
|
-
const [sending, setSending] =
|
|
1286
|
-
const [closing, setClosing] =
|
|
1287
|
-
const [reopening, setReopening] =
|
|
1288
|
-
const [composeShots, setComposeShots] =
|
|
1289
|
-
const [attachError, setAttachError] =
|
|
1352
|
+
const [detail, setDetail] = useState2(null);
|
|
1353
|
+
const [error, setError] = useState2(null);
|
|
1354
|
+
const [copied, setCopied] = useState2(false);
|
|
1355
|
+
const [editing, setEditing] = useState2(false);
|
|
1356
|
+
const [editBody, setEditBody] = useState2("");
|
|
1357
|
+
const [savingEdit, setSavingEdit] = useState2(false);
|
|
1358
|
+
const [editError, setEditError] = useState2(false);
|
|
1359
|
+
const [composeBody, setComposeBody] = useState2("");
|
|
1360
|
+
const [sending, setSending] = useState2(false);
|
|
1361
|
+
const [closing, setClosing] = useState2(false);
|
|
1362
|
+
const [reopening, setReopening] = useState2(false);
|
|
1363
|
+
const [composeShots, setComposeShots] = useState2([]);
|
|
1364
|
+
const [attachError, setAttachError] = useState2("");
|
|
1290
1365
|
const fileInputRef = useRef(null);
|
|
1291
1366
|
const mountedRef = useRef(true);
|
|
1292
1367
|
const urlPins = useRef(/* @__PURE__ */ new Map());
|
|
1293
|
-
const [, bumpPinTick] =
|
|
1368
|
+
const [, bumpPinTick] = useState2(0);
|
|
1294
1369
|
const PIN_MAX_AGE_MS = 45 * 6e4;
|
|
1295
1370
|
const pinUrl = (key, url) => {
|
|
1296
1371
|
if (!url) return url;
|
|
@@ -1474,7 +1549,7 @@ function ReportDetailView({
|
|
|
1474
1549
|
};
|
|
1475
1550
|
if (!detail && !error) {
|
|
1476
1551
|
if (seed) {
|
|
1477
|
-
const seedPill = /* @__PURE__ */
|
|
1552
|
+
const seedPill = /* @__PURE__ */ jsx3("span", { class: `pill pill-status pill-status--${seed.status}`, children: strings[`status.${seed.status}`] ?? seed.status });
|
|
1478
1553
|
return /* @__PURE__ */ jsxs3("div", { class: `report-detail variant-${variant} is-seeded`, children: [
|
|
1479
1554
|
variant === "modal" && /* @__PURE__ */ jsxs3("div", { class: "report-detail-header", children: [
|
|
1480
1555
|
/* @__PURE__ */ jsxs3("button", { type: "button", class: "btn", onClick: onBack, children: [
|
|
@@ -1500,19 +1575,19 @@ function ReportDetailView({
|
|
|
1500
1575
|
seedPill
|
|
1501
1576
|
] }),
|
|
1502
1577
|
/* @__PURE__ */ jsxs3("div", { class: "report-detail-body", children: [
|
|
1503
|
-
/* @__PURE__ */
|
|
1504
|
-
/* @__PURE__ */
|
|
1505
|
-
/* @__PURE__ */
|
|
1578
|
+
/* @__PURE__ */ jsx3("div", { class: "report-detail-description-row", children: /* @__PURE__ */ jsx3("p", { class: "report-detail-description", children: linkifySeq(seed.description, onOpenSeq) }) }),
|
|
1579
|
+
/* @__PURE__ */ jsx3("h3", { class: "report-detail-section", children: strings["detail.thread"] }),
|
|
1580
|
+
/* @__PURE__ */ jsx3("div", { class: "mine-loading", children: strings["mine.loading"] })
|
|
1506
1581
|
] })
|
|
1507
1582
|
] });
|
|
1508
1583
|
}
|
|
1509
|
-
return /* @__PURE__ */
|
|
1584
|
+
return /* @__PURE__ */ jsx3("div", { class: "mine-loading", children: strings["mine.loading"] });
|
|
1510
1585
|
}
|
|
1511
1586
|
if (!detail) {
|
|
1512
1587
|
if (error && error !== "load_failed") {
|
|
1513
1588
|
return /* @__PURE__ */ jsxs3("div", { class: "report-detail-empty-state", role: "alert", children: [
|
|
1514
|
-
/* @__PURE__ */
|
|
1515
|
-
/* @__PURE__ */
|
|
1589
|
+
/* @__PURE__ */ jsx3("p", { class: "report-detail-empty-state-body", children: error }),
|
|
1590
|
+
/* @__PURE__ */ jsx3("button", { type: "button", class: "btn", onClick: () => void fetchDetail(), children: strings["board.retry"] }),
|
|
1516
1591
|
/* @__PURE__ */ jsxs3("button", { type: "button", class: "btn", onClick: onBack, children: [
|
|
1517
1592
|
"\u2190 ",
|
|
1518
1593
|
strings["detail.load_failed.cta"]
|
|
@@ -1520,8 +1595,8 @@ function ReportDetailView({
|
|
|
1520
1595
|
] });
|
|
1521
1596
|
}
|
|
1522
1597
|
return /* @__PURE__ */ jsxs3("div", { class: "report-detail-empty-state", role: "alert", children: [
|
|
1523
|
-
/* @__PURE__ */
|
|
1524
|
-
/* @__PURE__ */
|
|
1598
|
+
/* @__PURE__ */ jsx3("p", { class: "report-detail-empty-state-title", children: strings["detail.load_failed.title"] }),
|
|
1599
|
+
/* @__PURE__ */ jsx3("p", { class: "report-detail-empty-state-body", children: strings["detail.load_failed.body"] }),
|
|
1525
1600
|
/* @__PURE__ */ jsxs3("button", { type: "button", class: "btn", onClick: onBack, children: [
|
|
1526
1601
|
"\u2190 ",
|
|
1527
1602
|
strings["detail.load_failed.cta"]
|
|
@@ -1538,7 +1613,7 @@ function ReportDetailView({
|
|
|
1538
1613
|
"\u2190 ",
|
|
1539
1614
|
strings["detail.back"]
|
|
1540
1615
|
] }),
|
|
1541
|
-
/* @__PURE__ */
|
|
1616
|
+
/* @__PURE__ */ jsx3("span", { class: `pill pill-status pill-status--${detail.status}`, children: strings[`status.${detail.status}`] ?? detail.status })
|
|
1542
1617
|
] }),
|
|
1543
1618
|
variant === "board" && /* @__PURE__ */ jsxs3("div", { class: "report-detail-header report-detail-header--board", children: [
|
|
1544
1619
|
/* @__PURE__ */ jsxs3(
|
|
@@ -1554,12 +1629,12 @@ function ReportDetailView({
|
|
|
1554
1629
|
]
|
|
1555
1630
|
}
|
|
1556
1631
|
),
|
|
1557
|
-
/* @__PURE__ */
|
|
1632
|
+
/* @__PURE__ */ jsx3("span", { class: `pill pill-status pill-status--${detail.status}`, children: strings[`status.${detail.status}`] ?? detail.status })
|
|
1558
1633
|
] }),
|
|
1559
1634
|
/* @__PURE__ */ jsxs3("div", { class: "report-detail-body", children: [
|
|
1560
|
-
/* @__PURE__ */
|
|
1635
|
+
/* @__PURE__ */ jsx3(ContextBlock, { detail, strings }),
|
|
1561
1636
|
editing ? /* @__PURE__ */ jsxs3("div", { class: "report-detail-edit", children: [
|
|
1562
|
-
/* @__PURE__ */
|
|
1637
|
+
/* @__PURE__ */ jsx3(
|
|
1563
1638
|
"textarea",
|
|
1564
1639
|
{
|
|
1565
1640
|
class: "report-detail-edit-input",
|
|
@@ -1571,9 +1646,9 @@ function ReportDetailView({
|
|
|
1571
1646
|
disabled: savingEdit
|
|
1572
1647
|
}
|
|
1573
1648
|
),
|
|
1574
|
-
editError && /* @__PURE__ */
|
|
1649
|
+
editError && /* @__PURE__ */ jsx3("p", { class: "error", role: "alert", children: strings["detail.edit_failed"] }),
|
|
1575
1650
|
/* @__PURE__ */ jsxs3("div", { class: "report-detail-edit-actions", children: [
|
|
1576
|
-
/* @__PURE__ */
|
|
1651
|
+
/* @__PURE__ */ jsx3(
|
|
1577
1652
|
"button",
|
|
1578
1653
|
{
|
|
1579
1654
|
type: "button",
|
|
@@ -1583,7 +1658,7 @@ function ReportDetailView({
|
|
|
1583
1658
|
children: strings["detail.edit_cancel"]
|
|
1584
1659
|
}
|
|
1585
1660
|
),
|
|
1586
|
-
/* @__PURE__ */
|
|
1661
|
+
/* @__PURE__ */ jsx3(
|
|
1587
1662
|
"button",
|
|
1588
1663
|
{
|
|
1589
1664
|
type: "button",
|
|
@@ -1595,8 +1670,8 @@ function ReportDetailView({
|
|
|
1595
1670
|
)
|
|
1596
1671
|
] })
|
|
1597
1672
|
] }) : /* @__PURE__ */ jsxs3("div", { class: "report-detail-description-row", children: [
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
isMine && /* @__PURE__ */
|
|
1673
|
+
/* @__PURE__ */ jsx3("p", { class: "report-detail-description", children: linkifySeq(detail.description, onOpenSeq) }),
|
|
1674
|
+
isMine && /* @__PURE__ */ jsx3(
|
|
1600
1675
|
"button",
|
|
1601
1676
|
{
|
|
1602
1677
|
type: "button",
|
|
@@ -1606,7 +1681,7 @@ function ReportDetailView({
|
|
|
1606
1681
|
}
|
|
1607
1682
|
)
|
|
1608
1683
|
] }),
|
|
1609
|
-
buildPermalink && /* @__PURE__ */
|
|
1684
|
+
buildPermalink && /* @__PURE__ */ jsx3("div", { class: "report-detail-permalink", children: /* @__PURE__ */ jsx3(
|
|
1610
1685
|
"button",
|
|
1611
1686
|
{
|
|
1612
1687
|
type: "button",
|
|
@@ -1617,19 +1692,19 @@ function ReportDetailView({
|
|
|
1617
1692
|
) }),
|
|
1618
1693
|
(detail.screenshots?.length ? detail.screenshots.map((s) => s.url) : [detail.screenshot_url]).map((url, i) => ({ url: pinUrl(`shot:${i}`, url ?? null), pinKey: `shot:${i}` })).filter((s) => Boolean(s.url)).map(({ url, pinKey }) => {
|
|
1619
1694
|
const safeHref = safeExternalHref(url);
|
|
1620
|
-
return safeHref ? /* @__PURE__ */
|
|
1695
|
+
return safeHref ? /* @__PURE__ */ jsx3(
|
|
1621
1696
|
"a",
|
|
1622
1697
|
{
|
|
1623
1698
|
class: "report-detail-screenshot",
|
|
1624
1699
|
href: safeHref,
|
|
1625
1700
|
target: "_blank",
|
|
1626
1701
|
rel: "noopener noreferrer",
|
|
1627
|
-
children: /* @__PURE__ */
|
|
1702
|
+
children: /* @__PURE__ */ jsx3("img", { src: url, alt: "", loading: "lazy", onError: () => unpinUrl(pinKey) })
|
|
1628
1703
|
}
|
|
1629
|
-
) : /* @__PURE__ */
|
|
1704
|
+
) : /* @__PURE__ */ jsx3("div", { class: "report-detail-screenshot", children: /* @__PURE__ */ jsx3("img", { src: url, alt: "", loading: "lazy", onError: () => unpinUrl(pinKey) }) });
|
|
1630
1705
|
}),
|
|
1631
|
-
/* @__PURE__ */
|
|
1632
|
-
detail.comments.length === 0 ? /* @__PURE__ */
|
|
1706
|
+
/* @__PURE__ */ jsx3("h3", { class: "report-detail-section", children: strings["detail.thread"] }),
|
|
1707
|
+
detail.comments.length === 0 ? /* @__PURE__ */ jsx3("p", { class: "report-detail-empty", children: strings["detail.no_replies"] }) : /* @__PURE__ */ jsx3("ul", { class: "report-comments", children: detail.comments.map((c) => /* @__PURE__ */ jsx3("li", { children: /* @__PURE__ */ jsx3(
|
|
1633
1708
|
CommentBubble,
|
|
1634
1709
|
{
|
|
1635
1710
|
comment: c,
|
|
@@ -1638,10 +1713,10 @@ function ReportDetailView({
|
|
|
1638
1713
|
stableUrl: (key, url) => pinUrl(key, url) ?? url
|
|
1639
1714
|
}
|
|
1640
1715
|
) })) }),
|
|
1641
|
-
detail.status_history && detail.status_history.length > 0 && /* @__PURE__ */
|
|
1642
|
-
detail.technical_context && /* @__PURE__ */
|
|
1716
|
+
detail.status_history && detail.status_history.length > 0 && /* @__PURE__ */ jsx3(StatusHistorySection, { rows: detail.status_history, strings }),
|
|
1717
|
+
detail.technical_context && /* @__PURE__ */ jsx3(TechnicalContextDrawer, { ctx: detail.technical_context, strings }),
|
|
1643
1718
|
showComposeBox ? /* @__PURE__ */ jsxs3("div", { class: "report-compose", children: [
|
|
1644
|
-
/* @__PURE__ */
|
|
1719
|
+
/* @__PURE__ */ jsx3(
|
|
1645
1720
|
"textarea",
|
|
1646
1721
|
{
|
|
1647
1722
|
value: composeBody,
|
|
@@ -1650,9 +1725,9 @@ function ReportDetailView({
|
|
|
1650
1725
|
disabled: sending
|
|
1651
1726
|
}
|
|
1652
1727
|
),
|
|
1653
|
-
composeShots.length > 0 && /* @__PURE__ */
|
|
1654
|
-
/* @__PURE__ */
|
|
1655
|
-
/* @__PURE__ */
|
|
1728
|
+
composeShots.length > 0 && /* @__PURE__ */ jsx3("div", { class: "compose-attachments", children: composeShots.map((s, i) => /* @__PURE__ */ jsxs3("div", { class: "compose-attachment", children: [
|
|
1729
|
+
/* @__PURE__ */ jsx3("img", { src: s.preview, alt: strings["detail.attachment_alt"] }),
|
|
1730
|
+
/* @__PURE__ */ jsx3(
|
|
1656
1731
|
"button",
|
|
1657
1732
|
{
|
|
1658
1733
|
type: "button",
|
|
@@ -1664,8 +1739,8 @@ function ReportDetailView({
|
|
|
1664
1739
|
}
|
|
1665
1740
|
)
|
|
1666
1741
|
] }, s.preview)) }),
|
|
1667
|
-
attachError && /* @__PURE__ */
|
|
1668
|
-
/* @__PURE__ */
|
|
1742
|
+
attachError && /* @__PURE__ */ jsx3("p", { class: "compose-attach-error", role: "alert", children: attachError }),
|
|
1743
|
+
/* @__PURE__ */ jsx3(
|
|
1669
1744
|
"input",
|
|
1670
1745
|
{
|
|
1671
1746
|
ref: fileInputRef,
|
|
@@ -1678,7 +1753,7 @@ function ReportDetailView({
|
|
|
1678
1753
|
}
|
|
1679
1754
|
),
|
|
1680
1755
|
/* @__PURE__ */ jsxs3("div", { class: "report-compose-actions", children: [
|
|
1681
|
-
/* @__PURE__ */
|
|
1756
|
+
/* @__PURE__ */ jsx3(
|
|
1682
1757
|
"button",
|
|
1683
1758
|
{
|
|
1684
1759
|
type: "button",
|
|
@@ -1688,7 +1763,7 @@ function ReportDetailView({
|
|
|
1688
1763
|
children: strings["detail.attach_add"]
|
|
1689
1764
|
}
|
|
1690
1765
|
),
|
|
1691
|
-
showCloseCta && /* @__PURE__ */
|
|
1766
|
+
showCloseCta && /* @__PURE__ */ jsx3(
|
|
1692
1767
|
"button",
|
|
1693
1768
|
{
|
|
1694
1769
|
type: "button",
|
|
@@ -1698,7 +1773,7 @@ function ReportDetailView({
|
|
|
1698
1773
|
children: closing ? strings["detail.close_busy"] : strings["detail.close_cta"]
|
|
1699
1774
|
}
|
|
1700
1775
|
),
|
|
1701
|
-
showCloseCta && /* @__PURE__ */
|
|
1776
|
+
showCloseCta && /* @__PURE__ */ jsx3(
|
|
1702
1777
|
"button",
|
|
1703
1778
|
{
|
|
1704
1779
|
type: "button",
|
|
@@ -1708,7 +1783,7 @@ function ReportDetailView({
|
|
|
1708
1783
|
children: reopening ? strings["detail.reopen_busy"] : strings["detail.reopen_cta"]
|
|
1709
1784
|
}
|
|
1710
1785
|
),
|
|
1711
|
-
/* @__PURE__ */
|
|
1786
|
+
/* @__PURE__ */ jsx3(
|
|
1712
1787
|
"button",
|
|
1713
1788
|
{
|
|
1714
1789
|
type: "button",
|
|
@@ -1724,9 +1799,9 @@ function ReportDetailView({
|
|
|
1724
1799
|
// to the submitter, so we hide the compose box entirely (action
|
|
1725
1800
|
// is genuinely unavailable) and surface a short notice so the
|
|
1726
1801
|
// viewer understands why.
|
|
1727
|
-
/* @__PURE__ */
|
|
1802
|
+
/* @__PURE__ */ jsx3("p", { class: "report-detail-teammate-notice", role: "note", children: strings["detail.teammate_notice"] })
|
|
1728
1803
|
),
|
|
1729
|
-
error && /* @__PURE__ */
|
|
1804
|
+
error && /* @__PURE__ */ jsx3("div", { class: "error", children: error })
|
|
1730
1805
|
] })
|
|
1731
1806
|
] });
|
|
1732
1807
|
}
|
|
@@ -1739,19 +1814,19 @@ function ContextBlock({ detail, strings }) {
|
|
|
1739
1814
|
const captureLabel = strings[captureKey] ?? detail.capture_method;
|
|
1740
1815
|
return /* @__PURE__ */ jsxs3("div", { class: "report-detail-context", children: [
|
|
1741
1816
|
/* @__PURE__ */ jsxs3("div", { class: "report-detail-context-pills", children: [
|
|
1742
|
-
/* @__PURE__ */
|
|
1743
|
-
/* @__PURE__ */
|
|
1744
|
-
/* @__PURE__ */
|
|
1817
|
+
/* @__PURE__ */ jsx3("span", { class: "pill pill-type", children: strings[`type.${detail.feedback_type}`] }),
|
|
1818
|
+
/* @__PURE__ */ jsx3("span", { class: `pill pill-severity pill-severity--${detail.severity}`, children: strings[`severity.${detail.severity}`] }),
|
|
1819
|
+
/* @__PURE__ */ jsx3("span", { class: "pill pill-capture", children: captureLabel })
|
|
1745
1820
|
] }),
|
|
1746
1821
|
/* @__PURE__ */ jsxs3("div", { class: "report-detail-context-line", children: [
|
|
1747
|
-
/* @__PURE__ */
|
|
1748
|
-
/* @__PURE__ */
|
|
1822
|
+
/* @__PURE__ */ jsx3("span", { class: "report-detail-context-label", children: strings["detail.context.submitted_at"] }),
|
|
1823
|
+
/* @__PURE__ */ jsx3("span", { children: formatSubmittedAt(detail.created_at) })
|
|
1749
1824
|
] }),
|
|
1750
1825
|
detail.page_url && (() => {
|
|
1751
1826
|
const safeHref = safeExternalHref(detail.page_url);
|
|
1752
1827
|
return /* @__PURE__ */ jsxs3("div", { class: "report-detail-context-line", title: detail.page_url, children: [
|
|
1753
|
-
/* @__PURE__ */
|
|
1754
|
-
safeHref ? /* @__PURE__ */
|
|
1828
|
+
/* @__PURE__ */ jsx3("span", { class: "report-detail-context-label", children: strings["detail.context.page"] }),
|
|
1829
|
+
safeHref ? /* @__PURE__ */ jsx3(
|
|
1755
1830
|
"a",
|
|
1756
1831
|
{
|
|
1757
1832
|
class: "report-detail-context-url",
|
|
@@ -1760,7 +1835,7 @@ function ContextBlock({ detail, strings }) {
|
|
|
1760
1835
|
rel: "noopener noreferrer",
|
|
1761
1836
|
children: truncateUrl(detail.page_url, 64)
|
|
1762
1837
|
}
|
|
1763
|
-
) : /* @__PURE__ */
|
|
1838
|
+
) : /* @__PURE__ */ jsx3("span", { class: "report-detail-context-url", children: truncateUrl(detail.page_url, 64) })
|
|
1764
1839
|
] });
|
|
1765
1840
|
})()
|
|
1766
1841
|
] });
|
|
@@ -1787,12 +1862,12 @@ function TechnicalContextDrawer({ ctx, strings }) {
|
|
|
1787
1862
|
const errorCount = errors.length;
|
|
1788
1863
|
const summary = errorCount > 0 ? `${strings["detail.tech.title"]} \xB7 ${errorCount} ${errorCount === 1 ? strings["detail.tech.errors_one"] : strings["detail.tech.errors_many"]}` : strings["detail.tech.title"];
|
|
1789
1864
|
return /* @__PURE__ */ jsxs3("details", { class: "report-detail-tech", children: [
|
|
1790
|
-
/* @__PURE__ */
|
|
1865
|
+
/* @__PURE__ */ jsx3("summary", { children: summary }),
|
|
1791
1866
|
/* @__PURE__ */ jsxs3("div", { class: "tech-body", children: [
|
|
1792
|
-
device && /* @__PURE__ */
|
|
1793
|
-
errors.length > 0 && /* @__PURE__ */
|
|
1794
|
-
consoleLogs.length > 0 && /* @__PURE__ */
|
|
1795
|
-
network.length > 0 && /* @__PURE__ */
|
|
1867
|
+
device && /* @__PURE__ */ jsx3(DeviceSection, { device, strings }),
|
|
1868
|
+
errors.length > 0 && /* @__PURE__ */ jsx3(ErrorsSection, { errors, strings }),
|
|
1869
|
+
consoleLogs.length > 0 && /* @__PURE__ */ jsx3(ConsoleSection, { logs: consoleLogs, strings }),
|
|
1870
|
+
network.length > 0 && /* @__PURE__ */ jsx3(NetworkSection, { rows: network, strings })
|
|
1796
1871
|
] })
|
|
1797
1872
|
] });
|
|
1798
1873
|
}
|
|
@@ -1814,10 +1889,10 @@ function DeviceSection({
|
|
|
1814
1889
|
if (device?.connection) parts.push({ label: strings["detail.tech.device.connection"], value: device.connection });
|
|
1815
1890
|
if (parts.length === 0) return null;
|
|
1816
1891
|
return /* @__PURE__ */ jsxs3("div", { class: "tech-section", children: [
|
|
1817
|
-
/* @__PURE__ */
|
|
1818
|
-
/* @__PURE__ */
|
|
1819
|
-
/* @__PURE__ */
|
|
1820
|
-
/* @__PURE__ */
|
|
1892
|
+
/* @__PURE__ */ jsx3("h4", { children: strings["detail.tech.device"] }),
|
|
1893
|
+
/* @__PURE__ */ jsx3("dl", { class: "tech-device", children: parts.map((p) => /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1894
|
+
/* @__PURE__ */ jsx3("dt", { children: p.label }),
|
|
1895
|
+
/* @__PURE__ */ jsx3("dd", { children: p.value })
|
|
1821
1896
|
] })) })
|
|
1822
1897
|
] });
|
|
1823
1898
|
}
|
|
@@ -1826,10 +1901,10 @@ function ErrorsSection({
|
|
|
1826
1901
|
strings
|
|
1827
1902
|
}) {
|
|
1828
1903
|
return /* @__PURE__ */ jsxs3("div", { class: "tech-section", children: [
|
|
1829
|
-
/* @__PURE__ */
|
|
1830
|
-
/* @__PURE__ */
|
|
1831
|
-
/* @__PURE__ */
|
|
1832
|
-
e.stack && /* @__PURE__ */
|
|
1904
|
+
/* @__PURE__ */ jsx3("h4", { children: strings["detail.tech.errors"] }),
|
|
1905
|
+
/* @__PURE__ */ jsx3("ul", { class: "tech-errors", children: errors.map((e) => /* @__PURE__ */ jsxs3("li", { children: [
|
|
1906
|
+
/* @__PURE__ */ jsx3("div", { class: "tech-errors-msg", children: e.message }),
|
|
1907
|
+
e.stack && /* @__PURE__ */ jsx3("pre", { class: "tech-errors-stack", children: truncateStack(e.stack) })
|
|
1833
1908
|
] })) })
|
|
1834
1909
|
] });
|
|
1835
1910
|
}
|
|
@@ -1838,10 +1913,10 @@ function ConsoleSection({
|
|
|
1838
1913
|
strings
|
|
1839
1914
|
}) {
|
|
1840
1915
|
return /* @__PURE__ */ jsxs3("div", { class: "tech-section", children: [
|
|
1841
|
-
/* @__PURE__ */
|
|
1842
|
-
/* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
1844
|
-
/* @__PURE__ */
|
|
1916
|
+
/* @__PURE__ */ jsx3("h4", { children: strings["detail.tech.console"] }),
|
|
1917
|
+
/* @__PURE__ */ jsx3("ul", { class: "tech-console", children: logs.map((l) => /* @__PURE__ */ jsxs3("li", { class: `tech-console-row tech-console-row--${l.level}`, children: [
|
|
1918
|
+
/* @__PURE__ */ jsx3("span", { class: "tech-console-level", children: l.level }),
|
|
1919
|
+
/* @__PURE__ */ jsx3("span", { class: "tech-console-msg", children: l.message })
|
|
1845
1920
|
] })) })
|
|
1846
1921
|
] });
|
|
1847
1922
|
}
|
|
@@ -1850,13 +1925,13 @@ function NetworkSection({
|
|
|
1850
1925
|
strings
|
|
1851
1926
|
}) {
|
|
1852
1927
|
return /* @__PURE__ */ jsxs3("div", { class: "tech-section", children: [
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
1928
|
+
/* @__PURE__ */ jsx3("h4", { children: strings["detail.tech.network"] }),
|
|
1929
|
+
/* @__PURE__ */ jsx3("ul", { class: "tech-network", children: rows.map((n) => {
|
|
1855
1930
|
const failed = n.status >= 400 || n.status === 0;
|
|
1856
1931
|
return /* @__PURE__ */ jsxs3("li", { class: `tech-network-row${failed ? " tech-network-row--fail" : ""}`, children: [
|
|
1857
|
-
/* @__PURE__ */
|
|
1858
|
-
/* @__PURE__ */
|
|
1859
|
-
/* @__PURE__ */
|
|
1932
|
+
/* @__PURE__ */ jsx3("span", { class: "tech-network-status", children: n.status || "\u2014" }),
|
|
1933
|
+
/* @__PURE__ */ jsx3("span", { class: "tech-network-method", children: n.method }),
|
|
1934
|
+
/* @__PURE__ */ jsx3("span", { class: "tech-network-url", title: n.url, children: truncateUrl(n.url, 56) }),
|
|
1860
1935
|
/* @__PURE__ */ jsxs3("span", { class: "tech-network-time", children: [
|
|
1861
1936
|
Math.round(n.durationMs),
|
|
1862
1937
|
"ms"
|
|
@@ -1872,26 +1947,26 @@ function truncateStack(stack) {
|
|
|
1872
1947
|
}
|
|
1873
1948
|
function StatusHistorySection({ rows, strings }) {
|
|
1874
1949
|
return /* @__PURE__ */ jsxs3("div", { class: "report-detail-history", children: [
|
|
1875
|
-
/* @__PURE__ */
|
|
1876
|
-
/* @__PURE__ */
|
|
1950
|
+
/* @__PURE__ */ jsx3("h3", { class: "report-detail-section", children: strings["detail.history"] }),
|
|
1951
|
+
/* @__PURE__ */ jsx3("ol", { class: "status-history", children: rows.map((r) => {
|
|
1877
1952
|
const from = strings[`status.${r.from_status}`] ?? r.from_status;
|
|
1878
1953
|
const to = strings[`status.${r.to_status}`] ?? r.to_status;
|
|
1879
1954
|
const sourceKey = r.changed_by_source === "mcp" ? "detail.author.mcp" : r.changed_by_source === "system" ? "detail.author.system" : "detail.author.staff";
|
|
1880
1955
|
return /* @__PURE__ */ jsxs3("li", { class: "status-history-row", children: [
|
|
1881
|
-
/* @__PURE__ */
|
|
1956
|
+
/* @__PURE__ */ jsx3("span", { class: "status-history-time", children: formatSubmittedAt(r.created_at) }),
|
|
1882
1957
|
/* @__PURE__ */ jsxs3("span", { class: "status-history-transition", children: [
|
|
1883
|
-
/* @__PURE__ */
|
|
1884
|
-
/* @__PURE__ */
|
|
1885
|
-
/* @__PURE__ */
|
|
1958
|
+
/* @__PURE__ */ jsx3("span", { class: `pill pill-status pill-status--${r.from_status}`, children: from }),
|
|
1959
|
+
/* @__PURE__ */ jsx3("span", { class: "status-history-arrow", "aria-hidden": "true", children: "\u2192" }),
|
|
1960
|
+
/* @__PURE__ */ jsx3("span", { class: `pill pill-status pill-status--${r.to_status}`, children: to })
|
|
1886
1961
|
] }),
|
|
1887
|
-
/* @__PURE__ */
|
|
1962
|
+
/* @__PURE__ */ jsx3("span", { class: `status-history-source status-history-source--${r.changed_by_source}`, children: strings[sourceKey] })
|
|
1888
1963
|
] });
|
|
1889
1964
|
}) })
|
|
1890
1965
|
] });
|
|
1891
1966
|
}
|
|
1892
1967
|
|
|
1893
1968
|
// src/widget/BoardView.tsx
|
|
1894
|
-
import { Fragment as Fragment2, jsx as
|
|
1969
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
1895
1970
|
var POLL_MS2 = 3e4;
|
|
1896
1971
|
var SEARCH_DEBOUNCE_MS = 300;
|
|
1897
1972
|
var SORT_OPTIONS = ["recent", "oldest", "updated", "severity", "status"];
|
|
@@ -1911,22 +1986,22 @@ function BoardView({
|
|
|
1911
1986
|
getCurrentPage,
|
|
1912
1987
|
initialSelectedId
|
|
1913
1988
|
}) {
|
|
1914
|
-
const [filters, setFilters] =
|
|
1915
|
-
const [thisPage, setThisPage] =
|
|
1989
|
+
const [filters, setFilters] = useState3(() => loadBoardView(externalId));
|
|
1990
|
+
const [thisPage, setThisPage] = useState3(true);
|
|
1916
1991
|
useEffect2(() => {
|
|
1917
1992
|
saveBoardView(externalId, filters);
|
|
1918
1993
|
}, [externalId, filtersHash(filters)]);
|
|
1919
|
-
const [page, setPage] =
|
|
1920
|
-
const [kpis, setKpis] =
|
|
1921
|
-
const [loading, setLoading] =
|
|
1922
|
-
const [stale, setStale] =
|
|
1923
|
-
const [error, setError] =
|
|
1924
|
-
const [selectedId, setSelectedId] =
|
|
1925
|
-
const [detailKey, setDetailKey] =
|
|
1926
|
-
const [reloadTick, setReloadTick] =
|
|
1927
|
-
const [extra, setExtra] =
|
|
1928
|
-
const [loadingMore, setLoadingMore] =
|
|
1929
|
-
const [qDraft, setQDraft] =
|
|
1994
|
+
const [page, setPage] = useState3(null);
|
|
1995
|
+
const [kpis, setKpis] = useState3(null);
|
|
1996
|
+
const [loading, setLoading] = useState3(true);
|
|
1997
|
+
const [stale, setStale] = useState3(false);
|
|
1998
|
+
const [error, setError] = useState3(null);
|
|
1999
|
+
const [selectedId, setSelectedId] = useState3(initialSelectedId ?? null);
|
|
2000
|
+
const [detailKey, setDetailKey] = useState3(0);
|
|
2001
|
+
const [reloadTick, setReloadTick] = useState3(0);
|
|
2002
|
+
const [extra, setExtra] = useState3(null);
|
|
2003
|
+
const [loadingMore, setLoadingMore] = useState3(false);
|
|
2004
|
+
const [qDraft, setQDraft] = useState3(filters.q ?? "");
|
|
1930
2005
|
const debouncedQ = useDebouncedValue(qDraft, SEARCH_DEBOUNCE_MS);
|
|
1931
2006
|
useEffect2(() => {
|
|
1932
2007
|
setFilters((f) => {
|
|
@@ -2033,8 +2108,8 @@ function BoardView({
|
|
|
2033
2108
|
setDetailKey((k) => k + 1);
|
|
2034
2109
|
};
|
|
2035
2110
|
return /* @__PURE__ */ jsxs4("div", { class: `board-view ${stale ? "is-stale" : ""}`, children: [
|
|
2036
|
-
/* @__PURE__ */
|
|
2037
|
-
/* @__PURE__ */
|
|
2111
|
+
/* @__PURE__ */ jsx4(BoardHeader, { strings, kpis, thisPage }),
|
|
2112
|
+
/* @__PURE__ */ jsx4(
|
|
2038
2113
|
BoardFilters,
|
|
2039
2114
|
{
|
|
2040
2115
|
filters,
|
|
@@ -2050,8 +2125,8 @@ function BoardView({
|
|
|
2050
2125
|
/* @__PURE__ */ jsxs4("div", { class: "board-body", children: [
|
|
2051
2126
|
/* @__PURE__ */ jsxs4("div", { class: "board-list-wrap", "aria-busy": loading, children: [
|
|
2052
2127
|
error && /* @__PURE__ */ jsxs4("div", { class: "board-error", role: "alert", children: [
|
|
2053
|
-
/* @__PURE__ */
|
|
2054
|
-
/* @__PURE__ */
|
|
2128
|
+
/* @__PURE__ */ jsx4("span", { children: error }),
|
|
2129
|
+
/* @__PURE__ */ jsx4(
|
|
2055
2130
|
"button",
|
|
2056
2131
|
{
|
|
2057
2132
|
type: "button",
|
|
@@ -2063,10 +2138,11 @@ function BoardView({
|
|
|
2063
2138
|
},
|
|
2064
2139
|
children: strings["board.retry"]
|
|
2065
2140
|
}
|
|
2066
|
-
)
|
|
2141
|
+
),
|
|
2142
|
+
/* @__PURE__ */ jsx4(DiagnosticHint, { api, strings, host: api.endpointHost })
|
|
2067
2143
|
] }),
|
|
2068
|
-
!error && loading && !page && /* @__PURE__ */
|
|
2069
|
-
!error && page && visibleRows.length === 0 && (!loading || stale) && /* @__PURE__ */
|
|
2144
|
+
!error && loading && !page && /* @__PURE__ */ jsx4(BoardListSkeleton, {}),
|
|
2145
|
+
!error && page && visibleRows.length === 0 && (!loading || stale) && /* @__PURE__ */ jsx4(
|
|
2070
2146
|
BoardEmpty,
|
|
2071
2147
|
{
|
|
2072
2148
|
strings,
|
|
@@ -2075,7 +2151,7 @@ function BoardView({
|
|
|
2075
2151
|
}
|
|
2076
2152
|
),
|
|
2077
2153
|
!error && page && visibleRows.length > 0 && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2078
|
-
/* @__PURE__ */
|
|
2154
|
+
/* @__PURE__ */ jsx4(
|
|
2079
2155
|
BoardList,
|
|
2080
2156
|
{
|
|
2081
2157
|
rows: visibleRows,
|
|
@@ -2086,7 +2162,7 @@ function BoardView({
|
|
|
2086
2162
|
thisPage
|
|
2087
2163
|
}
|
|
2088
2164
|
),
|
|
2089
|
-
hasMore && !stale && /* @__PURE__ */
|
|
2165
|
+
hasMore && !stale && /* @__PURE__ */ jsx4(
|
|
2090
2166
|
"button",
|
|
2091
2167
|
{
|
|
2092
2168
|
type: "button",
|
|
@@ -2098,7 +2174,7 @@ function BoardView({
|
|
|
2098
2174
|
)
|
|
2099
2175
|
] })
|
|
2100
2176
|
] }),
|
|
2101
|
-
/* @__PURE__ */
|
|
2177
|
+
/* @__PURE__ */ jsx4("div", { class: `board-detail-wrap ${selectedId ? "has-selection" : ""}`, children: selectedId ? /* @__PURE__ */ jsx4(
|
|
2102
2178
|
ReportDetailView,
|
|
2103
2179
|
{
|
|
2104
2180
|
api,
|
|
@@ -2119,8 +2195,8 @@ function BoardView({
|
|
|
2119
2195
|
},
|
|
2120
2196
|
detailKey
|
|
2121
2197
|
) : /* @__PURE__ */ jsxs4("div", { class: "board-detail-empty", children: [
|
|
2122
|
-
/* @__PURE__ */
|
|
2123
|
-
/* @__PURE__ */
|
|
2198
|
+
/* @__PURE__ */ jsx4(DetailEmptyIllustration, {}),
|
|
2199
|
+
/* @__PURE__ */ jsx4("p", { children: strings["board.detail.empty"] })
|
|
2124
2200
|
] }) })
|
|
2125
2201
|
] })
|
|
2126
2202
|
] });
|
|
@@ -2133,13 +2209,13 @@ function BoardHeader({
|
|
|
2133
2209
|
const scopeLabel = thisPage ? strings["board.scope.onThisPage"] : kpis?.scope === "project" ? strings["board.scope.project"] : strings["board.scope.mine"];
|
|
2134
2210
|
return /* @__PURE__ */ jsxs4("header", { class: "board-header", children: [
|
|
2135
2211
|
/* @__PURE__ */ jsxs4("div", { class: "board-header-title", children: [
|
|
2136
|
-
/* @__PURE__ */
|
|
2212
|
+
/* @__PURE__ */ jsx4("span", { class: "board-header-emoji", "aria-hidden": "true", children: "\u{1F4CB}" }),
|
|
2137
2213
|
/* @__PURE__ */ jsxs4("div", { children: [
|
|
2138
|
-
/* @__PURE__ */
|
|
2139
|
-
/* @__PURE__ */
|
|
2214
|
+
/* @__PURE__ */ jsx4("h2", { class: "board-header-h", children: strings["tab.board"] }),
|
|
2215
|
+
/* @__PURE__ */ jsx4("p", { class: "board-header-sub", children: kpis ? `${kpis.total} \xB7 ${scopeLabel}` : scopeLabel })
|
|
2140
2216
|
] })
|
|
2141
2217
|
] }),
|
|
2142
|
-
/* @__PURE__ */
|
|
2218
|
+
/* @__PURE__ */ jsx4(BoardKpiStrip, { kpis, strings })
|
|
2143
2219
|
] });
|
|
2144
2220
|
}
|
|
2145
2221
|
function BoardKpiStrip({
|
|
@@ -2172,9 +2248,9 @@ function BoardKpiStrip({
|
|
|
2172
2248
|
tone: "tone-rate"
|
|
2173
2249
|
}
|
|
2174
2250
|
];
|
|
2175
|
-
return /* @__PURE__ */
|
|
2176
|
-
/* @__PURE__ */
|
|
2177
|
-
/* @__PURE__ */
|
|
2251
|
+
return /* @__PURE__ */ jsx4("div", { class: `board-kpi-strip ${kpis ? "is-ready" : "is-loading"}`, "aria-live": "polite", children: cells.map((c) => /* @__PURE__ */ jsxs4("div", { class: `board-kpi-card ${c.tone}`, children: [
|
|
2252
|
+
/* @__PURE__ */ jsx4("div", { class: "board-kpi-value", children: c.value }),
|
|
2253
|
+
/* @__PURE__ */ jsx4("div", { class: "board-kpi-label", children: c.label })
|
|
2178
2254
|
] }, c.key)) });
|
|
2179
2255
|
}
|
|
2180
2256
|
function BoardFilters({
|
|
@@ -2227,7 +2303,7 @@ function BoardFilters({
|
|
|
2227
2303
|
const clear = () => onChange({});
|
|
2228
2304
|
return /* @__PURE__ */ jsxs4("div", { class: "board-filters", children: [
|
|
2229
2305
|
/* @__PURE__ */ jsxs4("div", { class: "board-scope", role: "group", "aria-label": strings["board.scope.thisPage"], children: [
|
|
2230
|
-
/* @__PURE__ */
|
|
2306
|
+
/* @__PURE__ */ jsx4(
|
|
2231
2307
|
"button",
|
|
2232
2308
|
{
|
|
2233
2309
|
type: "button",
|
|
@@ -2237,7 +2313,7 @@ function BoardFilters({
|
|
|
2237
2313
|
children: strings["board.scope.thisPage"]
|
|
2238
2314
|
}
|
|
2239
2315
|
),
|
|
2240
|
-
/* @__PURE__ */
|
|
2316
|
+
/* @__PURE__ */ jsx4(
|
|
2241
2317
|
"button",
|
|
2242
2318
|
{
|
|
2243
2319
|
type: "button",
|
|
@@ -2248,14 +2324,14 @@ function BoardFilters({
|
|
|
2248
2324
|
}
|
|
2249
2325
|
)
|
|
2250
2326
|
] }),
|
|
2251
|
-
/* @__PURE__ */
|
|
2327
|
+
/* @__PURE__ */ jsx4(
|
|
2252
2328
|
"select",
|
|
2253
2329
|
{
|
|
2254
2330
|
class: "board-filter-select",
|
|
2255
2331
|
"aria-label": strings["board.sort"],
|
|
2256
2332
|
value: filters.ordering ?? "recent",
|
|
2257
2333
|
onChange: (e) => setOrdering(e.target.value),
|
|
2258
|
-
children: SORT_OPTIONS.map((o) => /* @__PURE__ */
|
|
2334
|
+
children: SORT_OPTIONS.map((o) => /* @__PURE__ */ jsx4("option", { value: o, children: strings[`board.sort.${o}`] }, o))
|
|
2259
2335
|
}
|
|
2260
2336
|
),
|
|
2261
2337
|
/* @__PURE__ */ jsxs4(
|
|
@@ -2266,8 +2342,8 @@ function BoardFilters({
|
|
|
2266
2342
|
value: filters.status?.[0] ?? "",
|
|
2267
2343
|
onChange: (e) => setStatus(e.target.value),
|
|
2268
2344
|
children: [
|
|
2269
|
-
/* @__PURE__ */
|
|
2270
|
-
STATUSES.map((s) => /* @__PURE__ */
|
|
2345
|
+
/* @__PURE__ */ jsx4("option", { value: "", children: strings["board.filter.status"] }),
|
|
2346
|
+
STATUSES.map((s) => /* @__PURE__ */ jsx4("option", { value: s, children: strings[`board.kpi.${s}`] ?? s }, s))
|
|
2271
2347
|
]
|
|
2272
2348
|
}
|
|
2273
2349
|
),
|
|
@@ -2279,8 +2355,8 @@ function BoardFilters({
|
|
|
2279
2355
|
value: filters.type?.[0] ?? "",
|
|
2280
2356
|
onChange: (e) => setType(e.target.value),
|
|
2281
2357
|
children: [
|
|
2282
|
-
/* @__PURE__ */
|
|
2283
|
-
TYPES.map((t) => /* @__PURE__ */
|
|
2358
|
+
/* @__PURE__ */ jsx4("option", { value: "", children: strings["board.filter.type"] }),
|
|
2359
|
+
TYPES.map((t) => /* @__PURE__ */ jsx4("option", { value: t, children: strings[`type.${t}`] ?? t }, t))
|
|
2284
2360
|
]
|
|
2285
2361
|
}
|
|
2286
2362
|
),
|
|
@@ -2292,12 +2368,12 @@ function BoardFilters({
|
|
|
2292
2368
|
value: filters.severity?.[0] ?? "",
|
|
2293
2369
|
onChange: (e) => setSeverity(e.target.value),
|
|
2294
2370
|
children: [
|
|
2295
|
-
/* @__PURE__ */
|
|
2296
|
-
SEVERITIES.map((s) => /* @__PURE__ */
|
|
2371
|
+
/* @__PURE__ */ jsx4("option", { value: "", children: strings["board.filter.severity"] }),
|
|
2372
|
+
SEVERITIES.map((s) => /* @__PURE__ */ jsx4("option", { value: s, children: strings[`severity.${s}`] ?? s }, s))
|
|
2297
2373
|
]
|
|
2298
2374
|
}
|
|
2299
2375
|
),
|
|
2300
|
-
/* @__PURE__ */
|
|
2376
|
+
/* @__PURE__ */ jsx4(
|
|
2301
2377
|
"input",
|
|
2302
2378
|
{
|
|
2303
2379
|
type: "search",
|
|
@@ -2308,7 +2384,7 @@ function BoardFilters({
|
|
|
2308
2384
|
}
|
|
2309
2385
|
),
|
|
2310
2386
|
/* @__PURE__ */ jsxs4("label", { class: "board-filter-toggle", children: [
|
|
2311
|
-
/* @__PURE__ */
|
|
2387
|
+
/* @__PURE__ */ jsx4(
|
|
2312
2388
|
"input",
|
|
2313
2389
|
{
|
|
2314
2390
|
type: "checkbox",
|
|
@@ -2316,10 +2392,10 @@ function BoardFilters({
|
|
|
2316
2392
|
onChange: toggleMine
|
|
2317
2393
|
}
|
|
2318
2394
|
),
|
|
2319
|
-
/* @__PURE__ */
|
|
2395
|
+
/* @__PURE__ */ jsx4("span", { children: strings["board.filter.mine"] })
|
|
2320
2396
|
] }),
|
|
2321
2397
|
activeCount > 0 && /* @__PURE__ */ jsxs4("button", { type: "button", class: "board-filter-clear", onClick: clear, children: [
|
|
2322
|
-
/* @__PURE__ */
|
|
2398
|
+
/* @__PURE__ */ jsx4(CloseIcon, {}),
|
|
2323
2399
|
strings["board.filter.clear"]
|
|
2324
2400
|
] })
|
|
2325
2401
|
] });
|
|
@@ -2333,8 +2409,8 @@ function BoardList({
|
|
|
2333
2409
|
thisPage
|
|
2334
2410
|
}) {
|
|
2335
2411
|
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2336
|
-
/* @__PURE__ */
|
|
2337
|
-
/* @__PURE__ */
|
|
2412
|
+
/* @__PURE__ */ jsx4("div", { class: "board-list-count", children: strings[thisPage ? "board.list.count.page" : "board.list.count"].replace("{n}", String(rows.length)).replace("{total}", String(total)) }),
|
|
2413
|
+
/* @__PURE__ */ jsx4("ul", { class: "board-list", role: "list", children: rows.map((row) => /* @__PURE__ */ jsx4(
|
|
2338
2414
|
BoardRowCard,
|
|
2339
2415
|
{
|
|
2340
2416
|
row,
|
|
@@ -2353,7 +2429,7 @@ function BoardRowCard({
|
|
|
2353
2429
|
strings
|
|
2354
2430
|
}) {
|
|
2355
2431
|
const author = row.is_mine ? strings["board.list.you"] : row.author_label || "\u2014";
|
|
2356
|
-
return /* @__PURE__ */
|
|
2432
|
+
return /* @__PURE__ */ jsx4("li", { children: /* @__PURE__ */ jsxs4(
|
|
2357
2433
|
"button",
|
|
2358
2434
|
{
|
|
2359
2435
|
type: "button",
|
|
@@ -2362,18 +2438,18 @@ function BoardRowCard({
|
|
|
2362
2438
|
"aria-pressed": selected,
|
|
2363
2439
|
children: [
|
|
2364
2440
|
/* @__PURE__ */ jsxs4("div", { class: "board-row-badges", children: [
|
|
2365
|
-
/* @__PURE__ */
|
|
2366
|
-
/* @__PURE__ */
|
|
2441
|
+
/* @__PURE__ */ jsx4("span", { class: `badge status-${row.status}`, children: strings[`status.${row.status}`] ?? row.status }),
|
|
2442
|
+
/* @__PURE__ */ jsx4("span", { class: `badge severity-${row.severity}`, children: strings[`severity.${row.severity}`] ?? row.severity })
|
|
2367
2443
|
] }),
|
|
2368
|
-
/* @__PURE__ */
|
|
2444
|
+
/* @__PURE__ */ jsx4("div", { class: "board-row-description", children: row.description }),
|
|
2369
2445
|
/* @__PURE__ */ jsxs4("div", { class: "board-row-meta", children: [
|
|
2370
|
-
/* @__PURE__ */
|
|
2446
|
+
/* @__PURE__ */ jsx4("span", { class: "board-row-author", children: author }),
|
|
2371
2447
|
row.comment_count > 0 && /* @__PURE__ */ jsxs4("span", { class: "board-row-comments", children: [
|
|
2372
|
-
/* @__PURE__ */
|
|
2448
|
+
/* @__PURE__ */ jsx4(CommentIcon, {}),
|
|
2373
2449
|
" ",
|
|
2374
2450
|
row.comment_count
|
|
2375
2451
|
] }),
|
|
2376
|
-
/* @__PURE__ */
|
|
2452
|
+
/* @__PURE__ */ jsx4("span", { class: "board-row-time", children: formatRelative(row.created_at) })
|
|
2377
2453
|
] })
|
|
2378
2454
|
]
|
|
2379
2455
|
}
|
|
@@ -2385,44 +2461,44 @@ function BoardEmpty({
|
|
|
2385
2461
|
onAllPages
|
|
2386
2462
|
}) {
|
|
2387
2463
|
return /* @__PURE__ */ jsxs4("div", { class: "board-empty", children: [
|
|
2388
|
-
/* @__PURE__ */
|
|
2389
|
-
/* @__PURE__ */
|
|
2390
|
-
/* @__PURE__ */
|
|
2391
|
-
thisPage && /* @__PURE__ */
|
|
2464
|
+
/* @__PURE__ */ jsx4(EmptyIllustration, {}),
|
|
2465
|
+
/* @__PURE__ */ jsx4("h3", { children: strings[thisPage ? "board.list.empty.page.title" : "board.list.empty.title"] }),
|
|
2466
|
+
/* @__PURE__ */ jsx4("p", { children: strings[thisPage ? "board.list.empty.page.description" : "board.list.empty.description"] }),
|
|
2467
|
+
thisPage && /* @__PURE__ */ jsx4("button", { type: "button", class: "btn btn--ghost", onClick: onAllPages, children: strings["board.scope.allPages"] })
|
|
2392
2468
|
] });
|
|
2393
2469
|
}
|
|
2394
2470
|
function BoardListSkeleton() {
|
|
2395
|
-
return /* @__PURE__ */
|
|
2396
|
-
/* @__PURE__ */
|
|
2397
|
-
/* @__PURE__ */
|
|
2398
|
-
/* @__PURE__ */
|
|
2471
|
+
return /* @__PURE__ */ jsx4("ul", { class: "board-list board-list-skeleton", "aria-hidden": "true", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx4("li", { children: /* @__PURE__ */ jsxs4("div", { class: "board-row skeleton-row", children: [
|
|
2472
|
+
/* @__PURE__ */ jsx4("div", { class: "skeleton-line skeleton-badges" }),
|
|
2473
|
+
/* @__PURE__ */ jsx4("div", { class: "skeleton-line skeleton-text" }),
|
|
2474
|
+
/* @__PURE__ */ jsx4("div", { class: "skeleton-line skeleton-text short" })
|
|
2399
2475
|
] }) }, i)) });
|
|
2400
2476
|
}
|
|
2401
2477
|
function CommentIcon() {
|
|
2402
|
-
return /* @__PURE__ */
|
|
2478
|
+
return /* @__PURE__ */ jsx4("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx4("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
|
|
2403
2479
|
}
|
|
2404
2480
|
function CloseIcon() {
|
|
2405
2481
|
return /* @__PURE__ */ jsxs4("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: [
|
|
2406
|
-
/* @__PURE__ */
|
|
2407
|
-
/* @__PURE__ */
|
|
2482
|
+
/* @__PURE__ */ jsx4("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2483
|
+
/* @__PURE__ */ jsx4("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2408
2484
|
] });
|
|
2409
2485
|
}
|
|
2410
2486
|
function EmptyIllustration() {
|
|
2411
2487
|
return /* @__PURE__ */ jsxs4("svg", { width: "64", height: "64", viewBox: "0 0 64 64", fill: "none", "aria-hidden": "true", children: [
|
|
2412
|
-
/* @__PURE__ */
|
|
2413
|
-
/* @__PURE__ */
|
|
2488
|
+
/* @__PURE__ */ jsx4("circle", { cx: "32", cy: "32", r: "28", stroke: "currentColor", "stroke-opacity": "0.18", "stroke-width": "2" }),
|
|
2489
|
+
/* @__PURE__ */ jsx4("path", { d: "M22 32h20M32 22v20", stroke: "currentColor", "stroke-opacity": "0.35", "stroke-width": "2", "stroke-linecap": "round" })
|
|
2414
2490
|
] });
|
|
2415
2491
|
}
|
|
2416
2492
|
function DetailEmptyIllustration() {
|
|
2417
2493
|
return /* @__PURE__ */ jsxs4("svg", { width: "80", height: "80", viewBox: "0 0 64 64", fill: "none", "aria-hidden": "true", children: [
|
|
2418
|
-
/* @__PURE__ */
|
|
2419
|
-
/* @__PURE__ */
|
|
2420
|
-
/* @__PURE__ */
|
|
2421
|
-
/* @__PURE__ */
|
|
2494
|
+
/* @__PURE__ */ jsx4("rect", { x: "10", y: "12", width: "44", height: "36", rx: "4", stroke: "currentColor", "stroke-opacity": "0.22", "stroke-width": "2" }),
|
|
2495
|
+
/* @__PURE__ */ jsx4("line", { x1: "18", y1: "22", x2: "46", y2: "22", stroke: "currentColor", "stroke-opacity": "0.22", "stroke-width": "2", "stroke-linecap": "round" }),
|
|
2496
|
+
/* @__PURE__ */ jsx4("line", { x1: "18", y1: "30", x2: "38", y2: "30", stroke: "currentColor", "stroke-opacity": "0.18", "stroke-width": "2", "stroke-linecap": "round" }),
|
|
2497
|
+
/* @__PURE__ */ jsx4("line", { x1: "18", y1: "38", x2: "32", y2: "38", stroke: "currentColor", "stroke-opacity": "0.14", "stroke-width": "2", "stroke-linecap": "round" })
|
|
2422
2498
|
] });
|
|
2423
2499
|
}
|
|
2424
2500
|
function useDebouncedValue(value, ms) {
|
|
2425
|
-
const [debounced, setDebounced] =
|
|
2501
|
+
const [debounced, setDebounced] = useState3(value);
|
|
2426
2502
|
useEffect2(() => {
|
|
2427
2503
|
const t = setTimeout(() => setDebounced(value), ms);
|
|
2428
2504
|
return () => clearTimeout(t);
|
|
@@ -2482,10 +2558,10 @@ function formatRelative(iso) {
|
|
|
2482
2558
|
}
|
|
2483
2559
|
|
|
2484
2560
|
// src/widget/ChangelogList.tsx
|
|
2485
|
-
import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as
|
|
2561
|
+
import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState4 } from "preact/hooks";
|
|
2486
2562
|
|
|
2487
2563
|
// src/widget/ReportRow.tsx
|
|
2488
|
-
import { jsx as
|
|
2564
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
|
|
2489
2565
|
function statusClassName(status) {
|
|
2490
2566
|
return `pill pill-status pill-status--${status}`;
|
|
2491
2567
|
}
|
|
@@ -2515,13 +2591,13 @@ function ReportRow({ row, strings, onClick, extraMeta }) {
|
|
|
2515
2591
|
const preview = row.description.length > 120 ? row.description.slice(0, 117) + "\u2026" : row.description;
|
|
2516
2592
|
return /* @__PURE__ */ jsxs5("button", { type: "button", class: "mine-row", onClick, children: [
|
|
2517
2593
|
/* @__PURE__ */ jsxs5("div", { class: "mine-row-pills", children: [
|
|
2518
|
-
/* @__PURE__ */
|
|
2519
|
-
/* @__PURE__ */
|
|
2520
|
-
/* @__PURE__ */
|
|
2594
|
+
/* @__PURE__ */ jsx5("span", { class: statusClassName(row.status), children: strings[`status.${row.status}`] ?? row.status }),
|
|
2595
|
+
/* @__PURE__ */ jsx5("span", { class: typeClassName(), children: strings[`type.${row.feedback_type}`] }),
|
|
2596
|
+
/* @__PURE__ */ jsx5("span", { class: severityClassName(row.severity), children: strings[`severity.${row.severity}`] })
|
|
2521
2597
|
] }),
|
|
2522
|
-
/* @__PURE__ */
|
|
2598
|
+
/* @__PURE__ */ jsx5("div", { class: "mine-row-preview", children: preview }),
|
|
2523
2599
|
/* @__PURE__ */ jsxs5("div", { class: "mine-row-meta", children: [
|
|
2524
|
-
/* @__PURE__ */
|
|
2600
|
+
/* @__PURE__ */ jsx5("span", { children: formatRelative2(row.updated_at || row.created_at) }),
|
|
2525
2601
|
row.comment_count > 0 && /* @__PURE__ */ jsxs5("span", { children: [
|
|
2526
2602
|
"\xB7 ",
|
|
2527
2603
|
repliesLabel(row.comment_count, strings)
|
|
@@ -2535,7 +2611,7 @@ function ReportRow({ row, strings, onClick, extraMeta }) {
|
|
|
2535
2611
|
}
|
|
2536
2612
|
|
|
2537
2613
|
// src/widget/ChangelogList.tsx
|
|
2538
|
-
import { jsx as
|
|
2614
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
|
|
2539
2615
|
var POLL_MS3 = 3e4;
|
|
2540
2616
|
function isoWeekKey(iso) {
|
|
2541
2617
|
const d = new Date(iso);
|
|
@@ -2571,9 +2647,9 @@ function formatWeekLabel(weekKey) {
|
|
|
2571
2647
|
}
|
|
2572
2648
|
}
|
|
2573
2649
|
function ChangelogList({ api, externalId, strings, onSelect }) {
|
|
2574
|
-
const [rows, setRows] =
|
|
2575
|
-
const [error, setError] =
|
|
2576
|
-
const [refreshing, setRefreshing] =
|
|
2650
|
+
const [rows, setRows] = useState4(null);
|
|
2651
|
+
const [error, setError] = useState4(null);
|
|
2652
|
+
const [refreshing, setRefreshing] = useState4(false);
|
|
2577
2653
|
const mountedRef = useRef2(true);
|
|
2578
2654
|
const fetchRows = async () => {
|
|
2579
2655
|
setRefreshing(true);
|
|
@@ -2606,8 +2682,8 @@ function ChangelogList({ api, externalId, strings, onSelect }) {
|
|
|
2606
2682
|
const isEmpty = rows !== null && rows.length === 0;
|
|
2607
2683
|
return /* @__PURE__ */ jsxs6("div", { class: "mine-list", children: [
|
|
2608
2684
|
/* @__PURE__ */ jsxs6("div", { class: "mine-list-header", children: [
|
|
2609
|
-
/* @__PURE__ */
|
|
2610
|
-
/* @__PURE__ */
|
|
2685
|
+
/* @__PURE__ */ jsx6("h2", { children: strings["tab.changelog"] }),
|
|
2686
|
+
/* @__PURE__ */ jsx6(
|
|
2611
2687
|
"button",
|
|
2612
2688
|
{
|
|
2613
2689
|
type: "button",
|
|
@@ -2620,20 +2696,20 @@ function ChangelogList({ api, externalId, strings, onSelect }) {
|
|
|
2620
2696
|
}
|
|
2621
2697
|
)
|
|
2622
2698
|
] }),
|
|
2623
|
-
isLoading && /* @__PURE__ */
|
|
2624
|
-
error && /* @__PURE__ */
|
|
2699
|
+
isLoading && /* @__PURE__ */ jsx6("div", { class: "mine-loading", children: strings["mine.loading"] }),
|
|
2700
|
+
error && /* @__PURE__ */ jsx6("div", { class: "error", children: error }),
|
|
2625
2701
|
isEmpty && /* @__PURE__ */ jsxs6("div", { class: "mine-empty", children: [
|
|
2626
|
-
/* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2702
|
+
/* @__PURE__ */ jsx6("strong", { children: strings["changelog.empty.title"] }),
|
|
2703
|
+
/* @__PURE__ */ jsx6("p", { children: strings["changelog.empty.body"] })
|
|
2628
2704
|
] }),
|
|
2629
|
-
groups.length > 0 && /* @__PURE__ */
|
|
2705
|
+
groups.length > 0 && /* @__PURE__ */ jsx6("div", { class: "changelog-groups", children: groups.map((g) => /* @__PURE__ */ jsxs6("section", { class: "changelog-group", children: [
|
|
2630
2706
|
/* @__PURE__ */ jsxs6("header", { class: "changelog-group-header", children: [
|
|
2631
|
-
/* @__PURE__ */
|
|
2632
|
-
/* @__PURE__ */
|
|
2633
|
-
/* @__PURE__ */
|
|
2634
|
-
/* @__PURE__ */
|
|
2707
|
+
/* @__PURE__ */ jsx6("span", { class: "changelog-group-marker", "aria-hidden": "true", children: "\u25CF" }),
|
|
2708
|
+
/* @__PURE__ */ jsx6("span", { class: "changelog-group-label", children: strings["changelog.week_of"].replace("{date}", g.label) }),
|
|
2709
|
+
/* @__PURE__ */ jsx6("span", { class: "changelog-group-rule", "aria-hidden": "true" }),
|
|
2710
|
+
/* @__PURE__ */ jsx6("span", { class: "changelog-group-count", children: strings[g.rows.length === 1 ? "changelog.resolved_one" : "changelog.resolved_many"].replace("{count}", String(g.rows.length)) })
|
|
2635
2711
|
] }),
|
|
2636
|
-
/* @__PURE__ */
|
|
2712
|
+
/* @__PURE__ */ jsx6("ul", { class: "mine-rows", children: g.rows.map((row) => /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsx6(
|
|
2637
2713
|
ReportRow,
|
|
2638
2714
|
{
|
|
2639
2715
|
row,
|
|
@@ -2647,7 +2723,7 @@ function ChangelogList({ api, externalId, strings, onSelect }) {
|
|
|
2647
2723
|
}
|
|
2648
2724
|
|
|
2649
2725
|
// src/widget/Fab.tsx
|
|
2650
|
-
import { jsx as
|
|
2726
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
|
|
2651
2727
|
function BugIcon() {
|
|
2652
2728
|
return /* @__PURE__ */ jsxs7(
|
|
2653
2729
|
"svg",
|
|
@@ -2663,34 +2739,34 @@ function BugIcon() {
|
|
|
2663
2739
|
"aria-hidden": "true",
|
|
2664
2740
|
focusable: "false",
|
|
2665
2741
|
children: [
|
|
2666
|
-
/* @__PURE__ */
|
|
2667
|
-
/* @__PURE__ */
|
|
2668
|
-
/* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
2671
|
-
/* @__PURE__ */
|
|
2672
|
-
/* @__PURE__ */
|
|
2673
|
-
/* @__PURE__ */
|
|
2674
|
-
/* @__PURE__ */
|
|
2675
|
-
/* @__PURE__ */
|
|
2676
|
-
/* @__PURE__ */
|
|
2742
|
+
/* @__PURE__ */ jsx7("path", { d: "m8 2 1.88 1.88" }),
|
|
2743
|
+
/* @__PURE__ */ jsx7("path", { d: "M14.12 3.88 16 2" }),
|
|
2744
|
+
/* @__PURE__ */ jsx7("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
|
|
2745
|
+
/* @__PURE__ */ jsx7("path", { d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" }),
|
|
2746
|
+
/* @__PURE__ */ jsx7("path", { d: "M12 20v-9" }),
|
|
2747
|
+
/* @__PURE__ */ jsx7("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
|
|
2748
|
+
/* @__PURE__ */ jsx7("path", { d: "M6 13H2" }),
|
|
2749
|
+
/* @__PURE__ */ jsx7("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
|
|
2750
|
+
/* @__PURE__ */ jsx7("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
|
|
2751
|
+
/* @__PURE__ */ jsx7("path", { d: "M22 13h-4" }),
|
|
2752
|
+
/* @__PURE__ */ jsx7("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
|
|
2677
2753
|
]
|
|
2678
2754
|
}
|
|
2679
2755
|
);
|
|
2680
2756
|
}
|
|
2681
2757
|
function Fab({ label, onClick, count }) {
|
|
2682
2758
|
return /* @__PURE__ */ jsxs7("button", { type: "button", class: "fab", "aria-label": label, title: label, onClick, children: [
|
|
2683
|
-
/* @__PURE__ */
|
|
2684
|
-
count !== void 0 && count > 0 && /* @__PURE__ */
|
|
2759
|
+
/* @__PURE__ */ jsx7(BugIcon, {}),
|
|
2760
|
+
count !== void 0 && count > 0 && /* @__PURE__ */ jsx7("span", { class: "fab-badge", "aria-hidden": "true", children: count > 9 ? "9+" : String(count) })
|
|
2685
2761
|
] });
|
|
2686
2762
|
}
|
|
2687
2763
|
|
|
2688
2764
|
// src/widget/Form.tsx
|
|
2689
|
-
import { useEffect as useEffect5, useRef as useRef4, useState as
|
|
2765
|
+
import { useEffect as useEffect5, useRef as useRef4, useState as useState6 } from "preact/hooks";
|
|
2690
2766
|
|
|
2691
2767
|
// src/widget/Annotator.tsx
|
|
2692
|
-
import { useEffect as useEffect4, useLayoutEffect, useRef as useRef3, useState as
|
|
2693
|
-
import { jsx as
|
|
2768
|
+
import { useEffect as useEffect4, useLayoutEffect, useRef as useRef3, useState as useState5 } from "preact/hooks";
|
|
2769
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
2694
2770
|
var COLORS = ["#ef4444", "#f59e0b", "#10b981", "#3b82f6", "#ffffff"];
|
|
2695
2771
|
var HIGHLIGHT_ALPHA = 0.35;
|
|
2696
2772
|
function drawShape(ctx, shape, sourceImage) {
|
|
@@ -2812,43 +2888,43 @@ function drawBlur(ctx, shape, sourceImage) {
|
|
|
2812
2888
|
ctx.imageSmoothingEnabled = true;
|
|
2813
2889
|
}
|
|
2814
2890
|
var Icon = {
|
|
2815
|
-
rect: /* @__PURE__ */
|
|
2816
|
-
arrow: /* @__PURE__ */
|
|
2817
|
-
pencil: /* @__PURE__ */
|
|
2818
|
-
text: /* @__PURE__ */
|
|
2891
|
+
rect: /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("rect", { x: "2", y: "3", width: "12", height: "10", fill: "none", stroke: "currentColor", "stroke-width": "1.5" }) }),
|
|
2892
|
+
arrow: /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M2 8h11M9 4l4 4-4 4", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }) }),
|
|
2893
|
+
pencil: /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M11.5 2.5l2 2L5 13H3v-2l8.5-8.5z", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linejoin": "round" }) }),
|
|
2894
|
+
text: /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M3 3h10M8 3v10M5 13h6", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" }) }),
|
|
2819
2895
|
highlight: /* @__PURE__ */ jsxs8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: [
|
|
2820
|
-
/* @__PURE__ */
|
|
2821
|
-
/* @__PURE__ */
|
|
2896
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 13l3-3L11 5l-2-2-5 5-3 3v2h2zM10 4l2 2", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }),
|
|
2897
|
+
/* @__PURE__ */ jsx8("path", { d: "M2 14h12", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" })
|
|
2822
2898
|
] }),
|
|
2823
2899
|
blur: /* @__PURE__ */ jsxs8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: [
|
|
2824
|
-
/* @__PURE__ */
|
|
2825
|
-
/* @__PURE__ */
|
|
2826
|
-
/* @__PURE__ */
|
|
2827
|
-
/* @__PURE__ */
|
|
2828
|
-
/* @__PURE__ */
|
|
2829
|
-
/* @__PURE__ */
|
|
2830
|
-
/* @__PURE__ */
|
|
2831
|
-
/* @__PURE__ */
|
|
2832
|
-
/* @__PURE__ */
|
|
2900
|
+
/* @__PURE__ */ jsx8("rect", { x: "2", y: "2", width: "4", height: "4", fill: "currentColor", opacity: "0.85" }),
|
|
2901
|
+
/* @__PURE__ */ jsx8("rect", { x: "7", y: "2", width: "3", height: "3", fill: "currentColor", opacity: "0.55" }),
|
|
2902
|
+
/* @__PURE__ */ jsx8("rect", { x: "11", y: "2", width: "3", height: "4", fill: "currentColor", opacity: "0.4" }),
|
|
2903
|
+
/* @__PURE__ */ jsx8("rect", { x: "2", y: "7", width: "3", height: "3", fill: "currentColor", opacity: "0.6" }),
|
|
2904
|
+
/* @__PURE__ */ jsx8("rect", { x: "6", y: "7", width: "3", height: "3", fill: "currentColor", opacity: "0.85" }),
|
|
2905
|
+
/* @__PURE__ */ jsx8("rect", { x: "10", y: "7", width: "4", height: "3", fill: "currentColor", opacity: "0.5" }),
|
|
2906
|
+
/* @__PURE__ */ jsx8("rect", { x: "2", y: "11", width: "4", height: "3", fill: "currentColor", opacity: "0.4" }),
|
|
2907
|
+
/* @__PURE__ */ jsx8("rect", { x: "7", y: "11", width: "3", height: "3", fill: "currentColor", opacity: "0.65" }),
|
|
2908
|
+
/* @__PURE__ */ jsx8("rect", { x: "11", y: "11", width: "3", height: "3", fill: "currentColor", opacity: "0.85" })
|
|
2833
2909
|
] }),
|
|
2834
|
-
undo: /* @__PURE__ */
|
|
2835
|
-
redo: /* @__PURE__ */
|
|
2836
|
-
trash: /* @__PURE__ */
|
|
2837
|
-
close: /* @__PURE__ */
|
|
2910
|
+
undo: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M4 7l3-3M4 7l3 3M4 7h6a3 3 0 0 1 0 6H7", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }) }),
|
|
2911
|
+
redo: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M12 7l-3-3M12 7l-3 3M12 7H6a3 3 0 0 0 0 6h2", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }) }),
|
|
2912
|
+
trash: /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M3 4h10M6 4V2.5h4V4M5 4l.5 9h5L11 4", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }) }),
|
|
2913
|
+
close: /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "M4 4l8 8M12 4l-8 8", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" }) })
|
|
2838
2914
|
};
|
|
2839
2915
|
function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
2840
2916
|
const canvasRef = useRef3(null);
|
|
2841
2917
|
const containerRef = useRef3(null);
|
|
2842
2918
|
const imageRef = useRef3(null);
|
|
2843
|
-
const [tool, setTool] =
|
|
2844
|
-
const [color, setColor] =
|
|
2845
|
-
const [shapes, setShapes] =
|
|
2846
|
-
const [past, setPast] =
|
|
2847
|
-
const [future, setFuture] =
|
|
2919
|
+
const [tool, setTool] = useState5("rectangle");
|
|
2920
|
+
const [color, setColor] = useState5(COLORS[0]);
|
|
2921
|
+
const [shapes, setShapes] = useState5([]);
|
|
2922
|
+
const [past, setPast] = useState5([]);
|
|
2923
|
+
const [future, setFuture] = useState5([]);
|
|
2848
2924
|
const isDrawingRef = useRef3(false);
|
|
2849
|
-
const [draftShape, setDraftShape] =
|
|
2850
|
-
const [imageLoaded, setImageLoaded] =
|
|
2851
|
-
const [saving, setSaving] =
|
|
2925
|
+
const [draftShape, setDraftShape] = useState5(null);
|
|
2926
|
+
const [imageLoaded, setImageLoaded] = useState5(false);
|
|
2927
|
+
const [saving, setSaving] = useState5(false);
|
|
2852
2928
|
const scaleRef = useRef3(1);
|
|
2853
2929
|
function addShape(shape) {
|
|
2854
2930
|
setShapes((s) => {
|
|
@@ -3068,7 +3144,7 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3068
3144
|
{ id: "highlight", icon: Icon.highlight, label: strings["annotator.tool.highlight"] },
|
|
3069
3145
|
{ id: "blur", icon: Icon.blur, label: strings["annotator.tool.blur"] }
|
|
3070
3146
|
];
|
|
3071
|
-
return /* @__PURE__ */
|
|
3147
|
+
return /* @__PURE__ */ jsx8(
|
|
3072
3148
|
"div",
|
|
3073
3149
|
{
|
|
3074
3150
|
class: "annotator-backdrop",
|
|
@@ -3078,8 +3154,8 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3078
3154
|
},
|
|
3079
3155
|
children: /* @__PURE__ */ jsxs8("div", { class: "annotator", role: "dialog", "aria-modal": "true", "aria-label": strings["annotator.title"], children: [
|
|
3080
3156
|
/* @__PURE__ */ jsxs8("div", { class: "annotator-header", children: [
|
|
3081
|
-
/* @__PURE__ */
|
|
3082
|
-
/* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsx8("span", { children: strings["annotator.title"] }),
|
|
3158
|
+
/* @__PURE__ */ jsx8(
|
|
3083
3159
|
"button",
|
|
3084
3160
|
{
|
|
3085
3161
|
type: "button",
|
|
@@ -3091,7 +3167,7 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3091
3167
|
)
|
|
3092
3168
|
] }),
|
|
3093
3169
|
/* @__PURE__ */ jsxs8("div", { class: "annotator-toolbar", children: [
|
|
3094
|
-
/* @__PURE__ */
|
|
3170
|
+
/* @__PURE__ */ jsx8("div", { class: "annotator-tools", children: tools.map((t) => /* @__PURE__ */ jsx8(
|
|
3095
3171
|
"button",
|
|
3096
3172
|
{
|
|
3097
3173
|
type: "button",
|
|
@@ -3104,9 +3180,9 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3104
3180
|
},
|
|
3105
3181
|
t.id
|
|
3106
3182
|
)) }),
|
|
3107
|
-
/* @__PURE__ */
|
|
3183
|
+
/* @__PURE__ */ jsx8("span", { class: "annotator-sep" }),
|
|
3108
3184
|
/* @__PURE__ */ jsxs8("div", { class: "annotator-colors", children: [
|
|
3109
|
-
COLORS.map((c) => /* @__PURE__ */
|
|
3185
|
+
COLORS.map((c) => /* @__PURE__ */ jsx8(
|
|
3110
3186
|
"button",
|
|
3111
3187
|
{
|
|
3112
3188
|
type: "button",
|
|
@@ -3118,7 +3194,7 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3118
3194
|
},
|
|
3119
3195
|
c
|
|
3120
3196
|
)),
|
|
3121
|
-
/* @__PURE__ */
|
|
3197
|
+
/* @__PURE__ */ jsx8("label", { class: "annotator-color annotator-color-picker", title: strings["annotator.color_picker"], children: /* @__PURE__ */ jsx8(
|
|
3122
3198
|
"input",
|
|
3123
3199
|
{
|
|
3124
3200
|
type: "color",
|
|
@@ -3128,7 +3204,7 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3128
3204
|
}
|
|
3129
3205
|
) })
|
|
3130
3206
|
] }),
|
|
3131
|
-
/* @__PURE__ */
|
|
3207
|
+
/* @__PURE__ */ jsx8("span", { class: "annotator-sep" }),
|
|
3132
3208
|
/* @__PURE__ */ jsxs8(
|
|
3133
3209
|
"button",
|
|
3134
3210
|
{
|
|
@@ -3139,7 +3215,7 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3139
3215
|
title: strings["annotator.undo"],
|
|
3140
3216
|
children: [
|
|
3141
3217
|
Icon.undo,
|
|
3142
|
-
/* @__PURE__ */
|
|
3218
|
+
/* @__PURE__ */ jsx8("span", { children: strings["annotator.undo"] })
|
|
3143
3219
|
]
|
|
3144
3220
|
}
|
|
3145
3221
|
),
|
|
@@ -3153,7 +3229,7 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3153
3229
|
title: strings["annotator.redo"],
|
|
3154
3230
|
children: [
|
|
3155
3231
|
Icon.redo,
|
|
3156
|
-
/* @__PURE__ */
|
|
3232
|
+
/* @__PURE__ */ jsx8("span", { children: strings["annotator.redo"] })
|
|
3157
3233
|
]
|
|
3158
3234
|
}
|
|
3159
3235
|
),
|
|
@@ -3166,18 +3242,18 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3166
3242
|
disabled: shapes.length === 0,
|
|
3167
3243
|
children: [
|
|
3168
3244
|
Icon.trash,
|
|
3169
|
-
/* @__PURE__ */
|
|
3245
|
+
/* @__PURE__ */ jsx8("span", { children: strings["annotator.clear"] })
|
|
3170
3246
|
]
|
|
3171
3247
|
}
|
|
3172
3248
|
),
|
|
3173
|
-
/* @__PURE__ */
|
|
3249
|
+
/* @__PURE__ */ jsx8("span", { class: "annotator-spacer" }),
|
|
3174
3250
|
/* @__PURE__ */ jsxs8("span", { class: "annotator-count", children: [
|
|
3175
3251
|
shapes.length,
|
|
3176
3252
|
" ",
|
|
3177
3253
|
strings["annotator.count_suffix"]
|
|
3178
3254
|
] })
|
|
3179
3255
|
] }),
|
|
3180
|
-
/* @__PURE__ */
|
|
3256
|
+
/* @__PURE__ */ jsx8("div", { ref: containerRef, class: "annotator-canvas-wrap", children: !imageLoaded ? /* @__PURE__ */ jsx8("span", { class: "annotator-loading", children: strings["annotator.loading"] }) : /* @__PURE__ */ jsx8(
|
|
3181
3257
|
"canvas",
|
|
3182
3258
|
{
|
|
3183
3259
|
ref: canvasRef,
|
|
@@ -3189,8 +3265,8 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3189
3265
|
}
|
|
3190
3266
|
) }),
|
|
3191
3267
|
/* @__PURE__ */ jsxs8("div", { class: "annotator-footer", children: [
|
|
3192
|
-
/* @__PURE__ */
|
|
3193
|
-
/* @__PURE__ */
|
|
3268
|
+
/* @__PURE__ */ jsx8("button", { type: "button", class: "btn", onClick: onCancel, children: strings["form.cancel"] }),
|
|
3269
|
+
/* @__PURE__ */ jsx8(
|
|
3194
3270
|
"button",
|
|
3195
3271
|
{
|
|
3196
3272
|
type: "button",
|
|
@@ -3207,7 +3283,7 @@ function Annotator({ imageBlob, strings, onSave, onCancel }) {
|
|
|
3207
3283
|
}
|
|
3208
3284
|
|
|
3209
3285
|
// src/widget/Form.tsx
|
|
3210
|
-
import { jsx as
|
|
3286
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
3211
3287
|
var TYPES2 = ["bug", "feature", "question", "praise", "typo"];
|
|
3212
3288
|
var SEVERITIES2 = ["blocker", "high", "medium", "low"];
|
|
3213
3289
|
function Form({
|
|
@@ -3219,13 +3295,13 @@ function Form({
|
|
|
3219
3295
|
submittedSeq,
|
|
3220
3296
|
onDirtyChange
|
|
3221
3297
|
}) {
|
|
3222
|
-
const [description, setDescription] =
|
|
3223
|
-
const [feedbackType, setFeedbackType] =
|
|
3224
|
-
const [severity, setSeverity] =
|
|
3225
|
-
const [localError, setLocalError] =
|
|
3226
|
-
const [shots, setShots] =
|
|
3227
|
-
const [isDragOver, setIsDragOver] =
|
|
3228
|
-
const [annotatingIndex, setAnnotatingIndex] =
|
|
3298
|
+
const [description, setDescription] = useState6("");
|
|
3299
|
+
const [feedbackType, setFeedbackType] = useState6("bug");
|
|
3300
|
+
const [severity, setSeverity] = useState6("medium");
|
|
3301
|
+
const [localError, setLocalError] = useState6("");
|
|
3302
|
+
const [shots, setShots] = useState6([]);
|
|
3303
|
+
const [isDragOver, setIsDragOver] = useState6(false);
|
|
3304
|
+
const [annotatingIndex, setAnnotatingIndex] = useState6(null);
|
|
3229
3305
|
const fileInputRef = useRef4(null);
|
|
3230
3306
|
const dropZoneRef = useRef4(null);
|
|
3231
3307
|
const submitting = status === "submitting";
|
|
@@ -3347,10 +3423,10 @@ function Form({
|
|
|
3347
3423
|
onSubmit(values);
|
|
3348
3424
|
};
|
|
3349
3425
|
return /* @__PURE__ */ jsxs9("form", { onSubmit: handleSubmit, children: [
|
|
3350
|
-
/* @__PURE__ */
|
|
3426
|
+
/* @__PURE__ */ jsx9("h2", { children: strings["form.title"] }),
|
|
3351
3427
|
/* @__PURE__ */ jsxs9("div", { class: "field", children: [
|
|
3352
|
-
/* @__PURE__ */
|
|
3353
|
-
/* @__PURE__ */
|
|
3428
|
+
/* @__PURE__ */ jsx9("label", { for: "mfb-desc", children: strings["form.description.label"] }),
|
|
3429
|
+
/* @__PURE__ */ jsx9(
|
|
3354
3430
|
"textarea",
|
|
3355
3431
|
{
|
|
3356
3432
|
id: "mfb-desc",
|
|
@@ -3362,33 +3438,33 @@ function Form({
|
|
|
3362
3438
|
] }),
|
|
3363
3439
|
/* @__PURE__ */ jsxs9("div", { class: "row", children: [
|
|
3364
3440
|
/* @__PURE__ */ jsxs9("div", { class: "field", children: [
|
|
3365
|
-
/* @__PURE__ */
|
|
3366
|
-
/* @__PURE__ */
|
|
3441
|
+
/* @__PURE__ */ jsx9("label", { for: "mfb-type", children: strings["form.type.label"] }),
|
|
3442
|
+
/* @__PURE__ */ jsx9(
|
|
3367
3443
|
"select",
|
|
3368
3444
|
{
|
|
3369
3445
|
id: "mfb-type",
|
|
3370
3446
|
value: feedbackType,
|
|
3371
3447
|
onChange: (e) => setFeedbackType(e.target.value),
|
|
3372
|
-
children: TYPES2.map((t) => /* @__PURE__ */
|
|
3448
|
+
children: TYPES2.map((t) => /* @__PURE__ */ jsx9("option", { value: t, children: strings[`type.${t}`] }))
|
|
3373
3449
|
}
|
|
3374
3450
|
)
|
|
3375
3451
|
] }),
|
|
3376
3452
|
/* @__PURE__ */ jsxs9("div", { class: "field", children: [
|
|
3377
|
-
/* @__PURE__ */
|
|
3378
|
-
/* @__PURE__ */
|
|
3453
|
+
/* @__PURE__ */ jsx9("label", { for: "mfb-sev", children: strings["form.severity.label"] }),
|
|
3454
|
+
/* @__PURE__ */ jsx9(
|
|
3379
3455
|
"select",
|
|
3380
3456
|
{
|
|
3381
3457
|
id: "mfb-sev",
|
|
3382
3458
|
value: severity,
|
|
3383
3459
|
onChange: (e) => setSeverity(e.target.value),
|
|
3384
|
-
children: SEVERITIES2.map((s) => /* @__PURE__ */
|
|
3460
|
+
children: SEVERITIES2.map((s) => /* @__PURE__ */ jsx9("option", { value: s, children: strings[`severity.${s}`] }))
|
|
3385
3461
|
}
|
|
3386
3462
|
)
|
|
3387
3463
|
] })
|
|
3388
3464
|
] }),
|
|
3389
3465
|
/* @__PURE__ */ jsxs9("div", { class: "field", children: [
|
|
3390
|
-
/* @__PURE__ */
|
|
3391
|
-
/* @__PURE__ */
|
|
3466
|
+
/* @__PURE__ */ jsx9("label", { children: strings["form.screenshot.label"] }),
|
|
3467
|
+
/* @__PURE__ */ jsx9(
|
|
3392
3468
|
"input",
|
|
3393
3469
|
{
|
|
3394
3470
|
ref: fileInputRef,
|
|
@@ -3401,8 +3477,8 @@ function Form({
|
|
|
3401
3477
|
tabIndex: -1
|
|
3402
3478
|
}
|
|
3403
3479
|
),
|
|
3404
|
-
shots.length > 0 && /* @__PURE__ */
|
|
3405
|
-
/* @__PURE__ */
|
|
3480
|
+
shots.length > 0 && /* @__PURE__ */ jsx9("div", { class: "screenshot-strip", children: shots.map((shot, index) => /* @__PURE__ */ jsxs9("div", { class: "screenshot-preview", children: [
|
|
3481
|
+
/* @__PURE__ */ jsx9("img", { src: shot.preview, alt: "" }),
|
|
3406
3482
|
/* @__PURE__ */ jsxs9("div", { class: "screenshot-preview-actions", children: [
|
|
3407
3483
|
/* @__PURE__ */ jsxs9(
|
|
3408
3484
|
"button",
|
|
@@ -3412,15 +3488,15 @@ function Form({
|
|
|
3412
3488
|
onClick: () => setAnnotatingIndex(index),
|
|
3413
3489
|
children: [
|
|
3414
3490
|
/* @__PURE__ */ jsxs9("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: [
|
|
3415
|
-
/* @__PURE__ */
|
|
3416
|
-
/* @__PURE__ */
|
|
3491
|
+
/* @__PURE__ */ jsx9("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
|
|
3492
|
+
/* @__PURE__ */ jsx9("path", { d: "M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
|
|
3417
3493
|
] }),
|
|
3418
3494
|
strings["form.screenshot.annotate"]
|
|
3419
3495
|
]
|
|
3420
3496
|
}
|
|
3421
3497
|
),
|
|
3422
3498
|
/* @__PURE__ */ jsxs9("button", { type: "button", class: "btn", onClick: () => removeShot(index), children: [
|
|
3423
|
-
/* @__PURE__ */
|
|
3499
|
+
/* @__PURE__ */ jsx9("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx9("path", { d: "M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2m3 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6h14z" }) }),
|
|
3424
3500
|
strings["form.screenshot.remove"]
|
|
3425
3501
|
] })
|
|
3426
3502
|
] })
|
|
@@ -3445,33 +3521,33 @@ function Form({
|
|
|
3445
3521
|
onDrop: handleDrop,
|
|
3446
3522
|
children: [
|
|
3447
3523
|
/* @__PURE__ */ jsxs9("svg", { class: "screenshot-icon", width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.6", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: [
|
|
3448
|
-
/* @__PURE__ */
|
|
3449
|
-
/* @__PURE__ */
|
|
3450
|
-
/* @__PURE__ */
|
|
3524
|
+
/* @__PURE__ */ jsx9("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
3525
|
+
/* @__PURE__ */ jsx9("polyline", { points: "17 8 12 3 7 8" }),
|
|
3526
|
+
/* @__PURE__ */ jsx9("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
|
|
3451
3527
|
] }),
|
|
3452
3528
|
/* @__PURE__ */ jsxs9("div", { class: "screenshot-cta", children: [
|
|
3453
|
-
/* @__PURE__ */
|
|
3529
|
+
/* @__PURE__ */ jsx9("strong", { children: strings["form.screenshot.cta_click"] }),
|
|
3454
3530
|
", ",
|
|
3455
3531
|
strings["form.screenshot.cta_rest"]
|
|
3456
3532
|
] }),
|
|
3457
|
-
/* @__PURE__ */
|
|
3533
|
+
/* @__PURE__ */ jsx9("div", { class: "screenshot-formats", children: strings["form.screenshot.formats"] })
|
|
3458
3534
|
]
|
|
3459
3535
|
}
|
|
3460
3536
|
)
|
|
3461
3537
|
] }),
|
|
3462
3538
|
pageUrl && /* @__PURE__ */ jsxs9("div", { class: "page-context", title: pageUrl, children: [
|
|
3463
|
-
/* @__PURE__ */
|
|
3464
|
-
/* @__PURE__ */
|
|
3539
|
+
/* @__PURE__ */ jsx9("span", { class: "page-context-label", children: strings["form.context.label"] }),
|
|
3540
|
+
/* @__PURE__ */ jsx9("span", { class: "page-context-url", children: truncateUrl(pageUrl, 90) })
|
|
3465
3541
|
] }),
|
|
3466
|
-
/* @__PURE__ */
|
|
3467
|
-
localError && /* @__PURE__ */
|
|
3468
|
-
status === "error" && errorMessage && /* @__PURE__ */
|
|
3469
|
-
status === "success" && /* @__PURE__ */
|
|
3542
|
+
/* @__PURE__ */ jsx9("div", { class: "capture-notice", children: strings["form.capture.notice"] }),
|
|
3543
|
+
localError && /* @__PURE__ */ jsx9("div", { class: "error", children: localError }),
|
|
3544
|
+
status === "error" && errorMessage && /* @__PURE__ */ jsx9("div", { class: "error", children: errorMessage }),
|
|
3545
|
+
status === "success" && /* @__PURE__ */ jsx9("div", { class: "success", children: submittedSeq !== void 0 ? strings["form.success.seq"].replace("{seq}", String(submittedSeq)) : strings["form.success"] }),
|
|
3470
3546
|
/* @__PURE__ */ jsxs9("div", { class: "actions", children: [
|
|
3471
|
-
/* @__PURE__ */
|
|
3472
|
-
/* @__PURE__ */
|
|
3547
|
+
/* @__PURE__ */ jsx9("button", { type: "button", class: "btn", onClick: onCancel, disabled: submitting, children: strings["form.cancel"] }),
|
|
3548
|
+
/* @__PURE__ */ jsx9("button", { type: "submit", class: "btn btn--primary", disabled: submitting, children: submitLabel })
|
|
3473
3549
|
] }),
|
|
3474
|
-
annotatingIndex !== null && shots[annotatingIndex] && /* @__PURE__ */
|
|
3550
|
+
annotatingIndex !== null && shots[annotatingIndex] && /* @__PURE__ */ jsx9(
|
|
3475
3551
|
Annotator,
|
|
3476
3552
|
{
|
|
3477
3553
|
imageBlob: shots[annotatingIndex].blob,
|
|
@@ -3484,10 +3560,10 @@ function Form({
|
|
|
3484
3560
|
}
|
|
3485
3561
|
|
|
3486
3562
|
// src/widget/MineList.tsx
|
|
3487
|
-
import { useEffect as useEffect6, useRef as useRef5, useState as
|
|
3563
|
+
import { useEffect as useEffect6, useRef as useRef5, useState as useState7 } from "preact/hooks";
|
|
3488
3564
|
|
|
3489
3565
|
// src/widget/KpiStrip.tsx
|
|
3490
|
-
import { jsx as
|
|
3566
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
3491
3567
|
function computeKpiCounts(rows) {
|
|
3492
3568
|
const counts = {
|
|
3493
3569
|
new: 0,
|
|
@@ -3554,7 +3630,7 @@ function KpiStrip({ rows, filter, onFilter, strings }) {
|
|
|
3554
3630
|
value: resolutionRate === null ? "\u2014" : `${resolutionRate}%`
|
|
3555
3631
|
}
|
|
3556
3632
|
];
|
|
3557
|
-
return /* @__PURE__ */
|
|
3633
|
+
return /* @__PURE__ */ jsx10("div", { class: "kpi-strip", role: "toolbar", children: cells.map((c) => {
|
|
3558
3634
|
const active = filter === c.key;
|
|
3559
3635
|
const toggleTo = active ? "all" : c.key;
|
|
3560
3636
|
return /* @__PURE__ */ jsxs10(
|
|
@@ -3565,8 +3641,8 @@ function KpiStrip({ rows, filter, onFilter, strings }) {
|
|
|
3565
3641
|
onClick: () => onFilter(toggleTo),
|
|
3566
3642
|
"aria-pressed": active,
|
|
3567
3643
|
children: [
|
|
3568
|
-
/* @__PURE__ */
|
|
3569
|
-
/* @__PURE__ */
|
|
3644
|
+
/* @__PURE__ */ jsx10("span", { class: "kpi-value", children: c.value }),
|
|
3645
|
+
/* @__PURE__ */ jsx10("span", { class: "kpi-label", children: c.label })
|
|
3570
3646
|
]
|
|
3571
3647
|
}
|
|
3572
3648
|
);
|
|
@@ -3574,16 +3650,16 @@ function KpiStrip({ rows, filter, onFilter, strings }) {
|
|
|
3574
3650
|
}
|
|
3575
3651
|
|
|
3576
3652
|
// src/widget/MineList.tsx
|
|
3577
|
-
import { jsx as
|
|
3653
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "preact/jsx-runtime";
|
|
3578
3654
|
var POLL_MS4 = 3e4;
|
|
3579
3655
|
function MineList({ api, externalId, strings, onSelect, onOpenSeq }) {
|
|
3580
|
-
const [rows, setRows] =
|
|
3581
|
-
const [error, setError] =
|
|
3582
|
-
const [refreshing, setRefreshing] =
|
|
3583
|
-
const [filter, setFilter] =
|
|
3584
|
-
const [jumpValue, setJumpValue] =
|
|
3585
|
-
const [jumpError, setJumpError] =
|
|
3586
|
-
const [jumping, setJumping] =
|
|
3656
|
+
const [rows, setRows] = useState7(null);
|
|
3657
|
+
const [error, setError] = useState7(null);
|
|
3658
|
+
const [refreshing, setRefreshing] = useState7(false);
|
|
3659
|
+
const [filter, setFilter] = useState7("all");
|
|
3660
|
+
const [jumpValue, setJumpValue] = useState7("");
|
|
3661
|
+
const [jumpError, setJumpError] = useState7(false);
|
|
3662
|
+
const [jumping, setJumping] = useState7(false);
|
|
3587
3663
|
const mountedRef = useRef5(true);
|
|
3588
3664
|
const handleJump = async (e) => {
|
|
3589
3665
|
e.preventDefault();
|
|
@@ -3635,10 +3711,10 @@ function MineList({ api, externalId, strings, onSelect, onOpenSeq }) {
|
|
|
3635
3711
|
const visibleEmpty = !!rows && rows.length > 0 && (visibleRows?.length ?? 0) === 0;
|
|
3636
3712
|
return /* @__PURE__ */ jsxs11("div", { class: "mine-list", children: [
|
|
3637
3713
|
/* @__PURE__ */ jsxs11("div", { class: "mine-list-header", children: [
|
|
3638
|
-
/* @__PURE__ */
|
|
3714
|
+
/* @__PURE__ */ jsx11("h2", { children: strings["tab.mine"] }),
|
|
3639
3715
|
/* @__PURE__ */ jsxs11("div", { class: "mine-list-header-actions", children: [
|
|
3640
3716
|
onOpenSeq && /* @__PURE__ */ jsxs11("form", { class: "mine-jump", onSubmit: handleJump, children: [
|
|
3641
|
-
/* @__PURE__ */
|
|
3717
|
+
/* @__PURE__ */ jsx11(
|
|
3642
3718
|
"input",
|
|
3643
3719
|
{
|
|
3644
3720
|
type: "text",
|
|
@@ -3653,9 +3729,9 @@ function MineList({ api, externalId, strings, onSelect, onOpenSeq }) {
|
|
|
3653
3729
|
disabled: jumping
|
|
3654
3730
|
}
|
|
3655
3731
|
),
|
|
3656
|
-
/* @__PURE__ */
|
|
3732
|
+
/* @__PURE__ */ jsx11("button", { type: "submit", class: "btn", disabled: jumping || !jumpValue.trim(), children: strings["mine.jump.go"] })
|
|
3657
3733
|
] }),
|
|
3658
|
-
/* @__PURE__ */
|
|
3734
|
+
/* @__PURE__ */ jsx11(
|
|
3659
3735
|
"button",
|
|
3660
3736
|
{
|
|
3661
3737
|
type: "button",
|
|
@@ -3669,22 +3745,25 @@ function MineList({ api, externalId, strings, onSelect, onOpenSeq }) {
|
|
|
3669
3745
|
)
|
|
3670
3746
|
] })
|
|
3671
3747
|
] }),
|
|
3672
|
-
jumpError && /* @__PURE__ */
|
|
3673
|
-
rows && rows.length > 0 && /* @__PURE__ */
|
|
3674
|
-
isLoading && /* @__PURE__ */
|
|
3675
|
-
error && /* @__PURE__ */
|
|
3748
|
+
jumpError && /* @__PURE__ */ jsx11("div", { class: "mine-jump-error error", role: "alert", children: strings["mine.jump.not_found"] }),
|
|
3749
|
+
rows && rows.length > 0 && /* @__PURE__ */ jsx11(KpiStrip, { rows, filter, onFilter: setFilter, strings }),
|
|
3750
|
+
isLoading && /* @__PURE__ */ jsx11("div", { class: "mine-loading", children: strings["mine.loading"] }),
|
|
3751
|
+
error && /* @__PURE__ */ jsxs11("div", { class: "error", children: [
|
|
3752
|
+
error,
|
|
3753
|
+
/* @__PURE__ */ jsx11(DiagnosticHint, { api, strings, host: api.endpointHost })
|
|
3754
|
+
] }),
|
|
3676
3755
|
isEmpty && /* @__PURE__ */ jsxs11("div", { class: "mine-empty", children: [
|
|
3677
|
-
/* @__PURE__ */
|
|
3678
|
-
/* @__PURE__ */
|
|
3756
|
+
/* @__PURE__ */ jsx11("strong", { children: strings["mine.empty.title"] }),
|
|
3757
|
+
/* @__PURE__ */ jsx11("p", { children: strings["mine.empty.body"] })
|
|
3679
3758
|
] }),
|
|
3680
|
-
visibleEmpty && /* @__PURE__ */
|
|
3681
|
-
visibleRows && visibleRows.length > 0 && /* @__PURE__ */
|
|
3759
|
+
visibleEmpty && /* @__PURE__ */ jsx11("div", { class: "mine-empty", children: /* @__PURE__ */ jsx11("p", { children: strings["mine.filter.empty"] }) }),
|
|
3760
|
+
visibleRows && visibleRows.length > 0 && /* @__PURE__ */ jsx11("ul", { class: "mine-rows", children: visibleRows.map((row) => /* @__PURE__ */ jsx11("li", { children: /* @__PURE__ */ jsx11(ReportRow, { row, strings, onClick: () => onSelect(row) }) })) })
|
|
3682
3761
|
] });
|
|
3683
3762
|
}
|
|
3684
3763
|
|
|
3685
3764
|
// src/widget/Modal.tsx
|
|
3686
3765
|
import { useEffect as useEffect7, useRef as useRef6 } from "preact/hooks";
|
|
3687
|
-
import { jsx as
|
|
3766
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "preact/jsx-runtime";
|
|
3688
3767
|
function Modal({ onDismiss, children, closeLabel = "Close", expanded = false }) {
|
|
3689
3768
|
const modalRef = useRef6(null);
|
|
3690
3769
|
const previouslyFocused = useRef6(null);
|
|
@@ -3710,7 +3789,7 @@ function Modal({ onDismiss, children, closeLabel = "Close", expanded = false })
|
|
|
3710
3789
|
if (prev && typeof prev.focus === "function") prev.focus();
|
|
3711
3790
|
};
|
|
3712
3791
|
}, [onDismiss]);
|
|
3713
|
-
return /* @__PURE__ */
|
|
3792
|
+
return /* @__PURE__ */ jsx12(
|
|
3714
3793
|
"div",
|
|
3715
3794
|
{
|
|
3716
3795
|
class: `backdrop ${expanded ? "is-expanded" : ""}`,
|
|
@@ -3726,7 +3805,7 @@ function Modal({ onDismiss, children, closeLabel = "Close", expanded = false })
|
|
|
3726
3805
|
role: "dialog",
|
|
3727
3806
|
"aria-modal": "true",
|
|
3728
3807
|
children: [
|
|
3729
|
-
/* @__PURE__ */
|
|
3808
|
+
/* @__PURE__ */ jsx12(
|
|
3730
3809
|
"button",
|
|
3731
3810
|
{
|
|
3732
3811
|
type: "button",
|
|
@@ -3745,7 +3824,7 @@ function Modal({ onDismiss, children, closeLabel = "Close", expanded = false })
|
|
|
3745
3824
|
}
|
|
3746
3825
|
|
|
3747
3826
|
// src/widget/PageActivityStrip.tsx
|
|
3748
|
-
import { jsx as
|
|
3827
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "preact/jsx-runtime";
|
|
3749
3828
|
function PageActivityStrip({
|
|
3750
3829
|
open,
|
|
3751
3830
|
strings,
|
|
@@ -3754,14 +3833,14 @@ function PageActivityStrip({
|
|
|
3754
3833
|
if (open === 0) return null;
|
|
3755
3834
|
const text = open === 1 ? strings["page.strip.text.one"] : strings["page.strip.text"].replace("{n}", String(open));
|
|
3756
3835
|
return /* @__PURE__ */ jsxs13("div", { class: "page-strip", children: [
|
|
3757
|
-
/* @__PURE__ */
|
|
3758
|
-
/* @__PURE__ */
|
|
3836
|
+
/* @__PURE__ */ jsx13("span", { children: text }),
|
|
3837
|
+
/* @__PURE__ */ jsx13("button", { type: "button", class: "page-strip-view", onClick: onView, children: strings["page.strip.view"] })
|
|
3759
3838
|
] });
|
|
3760
3839
|
}
|
|
3761
3840
|
|
|
3762
3841
|
// src/widget/PagePeekPanel.tsx
|
|
3763
|
-
import { useEffect as useEffect8, useState as
|
|
3764
|
-
import { jsx as
|
|
3842
|
+
import { useEffect as useEffect8, useState as useState8 } from "preact/hooks";
|
|
3843
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "preact/jsx-runtime";
|
|
3765
3844
|
function PagePeekPanel({
|
|
3766
3845
|
api,
|
|
3767
3846
|
externalId,
|
|
@@ -3772,8 +3851,8 @@ function PagePeekPanel({
|
|
|
3772
3851
|
onPickRow,
|
|
3773
3852
|
onSend
|
|
3774
3853
|
}) {
|
|
3775
|
-
const [rows, setRows] =
|
|
3776
|
-
const [failed, setFailed] =
|
|
3854
|
+
const [rows, setRows] = useState8(null);
|
|
3855
|
+
const [failed, setFailed] = useState8(false);
|
|
3777
3856
|
useEffect8(() => {
|
|
3778
3857
|
let cancelled = false;
|
|
3779
3858
|
const pagePath = currentPagePath(getCurrentPage !== void 0 ? { getCurrentPage } : {});
|
|
@@ -3790,11 +3869,11 @@ function PagePeekPanel({
|
|
|
3790
3869
|
};
|
|
3791
3870
|
}, [api, externalId]);
|
|
3792
3871
|
return /* @__PURE__ */ jsxs14("div", { class: "page-peek", role: "region", "aria-label": strings["page.peek.title"], children: [
|
|
3793
|
-
/* @__PURE__ */
|
|
3872
|
+
/* @__PURE__ */ jsx14("div", { class: "page-peek-title", children: strings["page.peek.title"] }),
|
|
3794
3873
|
rows === null && !failed && /* @__PURE__ */ jsxs14("div", { class: "page-peek-skeleton", "aria-hidden": "true", children: [
|
|
3795
|
-
/* @__PURE__ */
|
|
3874
|
+
/* @__PURE__ */ jsx14("div", {}),
|
|
3796
3875
|
" ",
|
|
3797
|
-
/* @__PURE__ */
|
|
3876
|
+
/* @__PURE__ */ jsx14("div", {})
|
|
3798
3877
|
] }),
|
|
3799
3878
|
rows !== null && rows.map((row) => /* @__PURE__ */ jsxs14(
|
|
3800
3879
|
"button",
|
|
@@ -3803,21 +3882,21 @@ function PagePeekPanel({
|
|
|
3803
3882
|
class: "page-peek-row",
|
|
3804
3883
|
onClick: () => onPickRow?.(row.id),
|
|
3805
3884
|
children: [
|
|
3806
|
-
/* @__PURE__ */
|
|
3807
|
-
/* @__PURE__ */
|
|
3885
|
+
/* @__PURE__ */ jsx14("span", { class: `page-peek-dot status-${row.status}`, "aria-hidden": "true" }),
|
|
3886
|
+
/* @__PURE__ */ jsx14("span", { class: "page-peek-desc", children: row.description })
|
|
3808
3887
|
]
|
|
3809
3888
|
},
|
|
3810
3889
|
row.id
|
|
3811
3890
|
)),
|
|
3812
3891
|
/* @__PURE__ */ jsxs14("div", { class: "page-peek-footer", children: [
|
|
3813
|
-
/* @__PURE__ */
|
|
3814
|
-
/* @__PURE__ */
|
|
3892
|
+
/* @__PURE__ */ jsx14("button", { type: "button", class: "page-peek-viewall", onClick: onViewAll, children: open === 1 ? strings["page.peek.viewAll.one"] : strings["page.peek.viewAll"].replace("{n}", String(open)) }),
|
|
3893
|
+
/* @__PURE__ */ jsx14("button", { type: "button", class: "page-peek-send", onClick: onSend, children: strings["fab.label"] })
|
|
3815
3894
|
] })
|
|
3816
3895
|
] });
|
|
3817
3896
|
}
|
|
3818
3897
|
|
|
3819
3898
|
// src/widget/pageSignal.ts
|
|
3820
|
-
import { useCallback, useEffect as useEffect9, useState as
|
|
3899
|
+
import { useCallback, useEffect as useEffect9, useState as useState9 } from "preact/hooks";
|
|
3821
3900
|
var TTL_MS2 = 6e4;
|
|
3822
3901
|
function computeOpenCount(kpis) {
|
|
3823
3902
|
const s = kpis.by_status;
|
|
@@ -3846,8 +3925,8 @@ function fetchOpen(api, externalId, path) {
|
|
|
3846
3925
|
}
|
|
3847
3926
|
function usePageOpenCount(opts) {
|
|
3848
3927
|
const { api, externalId, getCurrentPage, enabled } = opts;
|
|
3849
|
-
const [open, setOpen] =
|
|
3850
|
-
const [tick, setTick] =
|
|
3928
|
+
const [open, setOpen] = useState9(0);
|
|
3929
|
+
const [tick, setTick] = useState9(0);
|
|
3851
3930
|
const refresh = useCallback(() => {
|
|
3852
3931
|
invalidatePageSignal();
|
|
3853
3932
|
setTick((t) => t + 1);
|
|
@@ -5942,7 +6021,7 @@ button.report-detail-edit {
|
|
|
5942
6021
|
`;
|
|
5943
6022
|
|
|
5944
6023
|
// src/widget/mount.tsx
|
|
5945
|
-
import { Fragment as Fragment3, jsx as
|
|
6024
|
+
import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs15 } from "preact/jsx-runtime";
|
|
5946
6025
|
function computeFabVisible(opts, externalId, visibilityAllowed) {
|
|
5947
6026
|
if (!opts.showFAB) return false;
|
|
5948
6027
|
if (opts.getExternalId !== void 0 && !externalId) return false;
|
|
@@ -6040,7 +6119,7 @@ function mountWidget(options) {
|
|
|
6040
6119
|
enabled: pageActivityEnabled
|
|
6041
6120
|
});
|
|
6042
6121
|
const fabLabel = pageSignal.open === 1 ? options.strings["page.badge.aria.one"] : pageSignal.open > 0 ? options.strings["page.badge.aria"].replace("{n}", String(pageSignal.open)) : options.strings["fab.label"];
|
|
6043
|
-
const [visibilityAllowed, setVisibilityAllowed] =
|
|
6122
|
+
const [visibilityAllowed, setVisibilityAllowed] = useState10(
|
|
6044
6123
|
!options.requiresVisibilityCheck
|
|
6045
6124
|
);
|
|
6046
6125
|
useEffect10(() => {
|
|
@@ -6064,7 +6143,7 @@ function mountWidget(options) {
|
|
|
6064
6143
|
}, [externalId]);
|
|
6065
6144
|
const fabVisible = computeFabVisible(options, externalId, visibilityAllowed);
|
|
6066
6145
|
const showMineTab = Boolean(options.api && externalId);
|
|
6067
|
-
const [peekOpen, setPeekOpen] =
|
|
6146
|
+
const [peekOpen, setPeekOpen] = useState10(false);
|
|
6068
6147
|
const peekTimers = useRef7({});
|
|
6069
6148
|
const peekEnter = () => {
|
|
6070
6149
|
if (peekTimers.current.close) clearTimeout(peekTimers.current.close);
|
|
@@ -6088,7 +6167,7 @@ function mountWidget(options) {
|
|
|
6088
6167
|
onFocusOut: () => setPeekOpen(false),
|
|
6089
6168
|
onKeyDown: (e) => e.key === "Escape" && setPeekOpen(false),
|
|
6090
6169
|
children: [
|
|
6091
|
-
peekOpen && !state.open && pageActivityEnabled && pageSignal.open > 0 && options.api && externalId && /* @__PURE__ */
|
|
6170
|
+
peekOpen && !state.open && pageActivityEnabled && pageSignal.open > 0 && options.api && externalId && /* @__PURE__ */ jsx15(
|
|
6092
6171
|
PagePeekPanel,
|
|
6093
6172
|
{
|
|
6094
6173
|
api: options.api,
|
|
@@ -6112,7 +6191,7 @@ function mountWidget(options) {
|
|
|
6112
6191
|
}
|
|
6113
6192
|
}
|
|
6114
6193
|
),
|
|
6115
|
-
/* @__PURE__ */
|
|
6194
|
+
/* @__PURE__ */ jsx15(
|
|
6116
6195
|
Fab,
|
|
6117
6196
|
{
|
|
6118
6197
|
label: fabLabel,
|
|
@@ -6144,11 +6223,11 @@ function mountWidget(options) {
|
|
|
6144
6223
|
closeLabel: options.strings["form.close"],
|
|
6145
6224
|
expanded: state.tab === "board",
|
|
6146
6225
|
children: [
|
|
6147
|
-
state.confirmingDiscard && /* @__PURE__ */
|
|
6148
|
-
/* @__PURE__ */
|
|
6149
|
-
/* @__PURE__ */
|
|
6226
|
+
state.confirmingDiscard && /* @__PURE__ */ jsx15("div", { class: "discard-confirm", role: "alertdialog", "aria-modal": "true", children: /* @__PURE__ */ jsxs15("div", { class: "discard-confirm-card", children: [
|
|
6227
|
+
/* @__PURE__ */ jsx15("p", { class: "discard-confirm-title", children: options.strings["form.discard.title"] }),
|
|
6228
|
+
/* @__PURE__ */ jsx15("p", { class: "discard-confirm-body", children: options.strings["form.discard.body"] }),
|
|
6150
6229
|
/* @__PURE__ */ jsxs15("div", { class: "discard-confirm-actions", children: [
|
|
6151
|
-
/* @__PURE__ */
|
|
6230
|
+
/* @__PURE__ */ jsx15(
|
|
6152
6231
|
"button",
|
|
6153
6232
|
{
|
|
6154
6233
|
type: "button",
|
|
@@ -6157,7 +6236,7 @@ function mountWidget(options) {
|
|
|
6157
6236
|
children: options.strings["form.discard.keep"]
|
|
6158
6237
|
}
|
|
6159
6238
|
),
|
|
6160
|
-
/* @__PURE__ */
|
|
6239
|
+
/* @__PURE__ */ jsx15(
|
|
6161
6240
|
"button",
|
|
6162
6241
|
{
|
|
6163
6242
|
type: "button",
|
|
@@ -6179,7 +6258,7 @@ function mountWidget(options) {
|
|
|
6179
6258
|
] })
|
|
6180
6259
|
] }) }),
|
|
6181
6260
|
showMineTab && /* @__PURE__ */ jsxs15("div", { class: "tab-strip", role: "tablist", children: [
|
|
6182
|
-
/* @__PURE__ */
|
|
6261
|
+
/* @__PURE__ */ jsx15(
|
|
6183
6262
|
"button",
|
|
6184
6263
|
{
|
|
6185
6264
|
type: "button",
|
|
@@ -6190,7 +6269,7 @@ function mountWidget(options) {
|
|
|
6190
6269
|
children: options.strings["tab.send"]
|
|
6191
6270
|
}
|
|
6192
6271
|
),
|
|
6193
|
-
/* @__PURE__ */
|
|
6272
|
+
/* @__PURE__ */ jsx15(
|
|
6194
6273
|
"button",
|
|
6195
6274
|
{
|
|
6196
6275
|
type: "button",
|
|
@@ -6201,7 +6280,7 @@ function mountWidget(options) {
|
|
|
6201
6280
|
children: options.strings["tab.mine"]
|
|
6202
6281
|
}
|
|
6203
6282
|
),
|
|
6204
|
-
/* @__PURE__ */
|
|
6283
|
+
/* @__PURE__ */ jsx15(
|
|
6205
6284
|
"button",
|
|
6206
6285
|
{
|
|
6207
6286
|
type: "button",
|
|
@@ -6212,7 +6291,7 @@ function mountWidget(options) {
|
|
|
6212
6291
|
children: options.strings["tab.changelog"]
|
|
6213
6292
|
}
|
|
6214
6293
|
),
|
|
6215
|
-
/* @__PURE__ */
|
|
6294
|
+
/* @__PURE__ */ jsx15(
|
|
6216
6295
|
"button",
|
|
6217
6296
|
{
|
|
6218
6297
|
type: "button",
|
|
@@ -6225,7 +6304,7 @@ function mountWidget(options) {
|
|
|
6225
6304
|
)
|
|
6226
6305
|
] }),
|
|
6227
6306
|
state.tab === "send" && /* @__PURE__ */ jsxs15(Fragment3, { children: [
|
|
6228
|
-
showMineTab && pageActivityEnabled && /* @__PURE__ */
|
|
6307
|
+
showMineTab && pageActivityEnabled && /* @__PURE__ */ jsx15(
|
|
6229
6308
|
PageActivityStrip,
|
|
6230
6309
|
{
|
|
6231
6310
|
open: pageSignal.open,
|
|
@@ -6233,7 +6312,7 @@ function mountWidget(options) {
|
|
|
6233
6312
|
onView: () => rerender(clearSelected({ ...currentState, tab: "board" }))
|
|
6234
6313
|
}
|
|
6235
6314
|
),
|
|
6236
|
-
/* @__PURE__ */
|
|
6315
|
+
/* @__PURE__ */ jsx15(
|
|
6237
6316
|
Form,
|
|
6238
6317
|
{
|
|
6239
6318
|
strings: options.strings,
|
|
@@ -6250,7 +6329,7 @@ function mountWidget(options) {
|
|
|
6250
6329
|
}
|
|
6251
6330
|
)
|
|
6252
6331
|
] }),
|
|
6253
|
-
state.tab === "mine" && options.api && externalId && !state.selectedReportId && /* @__PURE__ */
|
|
6332
|
+
state.tab === "mine" && options.api && externalId && !state.selectedReportId && /* @__PURE__ */ jsx15(
|
|
6254
6333
|
MineList,
|
|
6255
6334
|
{
|
|
6256
6335
|
api: options.api,
|
|
@@ -6260,7 +6339,7 @@ function mountWidget(options) {
|
|
|
6260
6339
|
onOpenSeq: openSeq
|
|
6261
6340
|
}
|
|
6262
6341
|
),
|
|
6263
|
-
(state.tab === "mine" || state.tab === "changelog") && options.api && externalId && state.selectedReportId && /* @__PURE__ */
|
|
6342
|
+
(state.tab === "mine" || state.tab === "changelog") && options.api && externalId && state.selectedReportId && /* @__PURE__ */ jsx15(
|
|
6264
6343
|
ReportDetailView,
|
|
6265
6344
|
{
|
|
6266
6345
|
api: options.api,
|
|
@@ -6272,7 +6351,7 @@ function mountWidget(options) {
|
|
|
6272
6351
|
...buildPermalink && { buildPermalink }
|
|
6273
6352
|
}
|
|
6274
6353
|
),
|
|
6275
|
-
state.tab === "changelog" && options.api && externalId && !state.selectedReportId && /* @__PURE__ */
|
|
6354
|
+
state.tab === "changelog" && options.api && externalId && !state.selectedReportId && /* @__PURE__ */ jsx15(
|
|
6276
6355
|
ChangelogList,
|
|
6277
6356
|
{
|
|
6278
6357
|
api: options.api,
|
|
@@ -6283,7 +6362,7 @@ function mountWidget(options) {
|
|
|
6283
6362
|
),
|
|
6284
6363
|
state.tab === "board" && options.api && externalId && // BoardView owns its own master/detail navigation — no
|
|
6285
6364
|
// selectedReportId routing through the modal-level state.
|
|
6286
|
-
/* @__PURE__ */
|
|
6365
|
+
/* @__PURE__ */ jsx15(
|
|
6287
6366
|
BoardView,
|
|
6288
6367
|
{
|
|
6289
6368
|
api: options.api,
|
|
@@ -6404,8 +6483,8 @@ function createFeedback(config) {
|
|
|
6404
6483
|
capture_method: captureMethod,
|
|
6405
6484
|
technical_context
|
|
6406
6485
|
};
|
|
6407
|
-
if ("0.
|
|
6408
|
-
payload.widget_version = "0.
|
|
6486
|
+
if ("0.33.0") {
|
|
6487
|
+
payload.widget_version = "0.33.0";
|
|
6409
6488
|
}
|
|
6410
6489
|
if (manualScreenshots?.length) {
|
|
6411
6490
|
payload.screenshots = manualScreenshots;
|
|
@@ -6531,4 +6610,4 @@ function createFeedback(config) {
|
|
|
6531
6610
|
export {
|
|
6532
6611
|
createFeedback
|
|
6533
6612
|
};
|
|
6534
|
-
//# sourceMappingURL=chunk-
|
|
6613
|
+
//# sourceMappingURL=chunk-RR6UB75B.mjs.map
|