@mhosaic/feedback 0.19.0 → 0.20.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.
@@ -195,6 +195,7 @@ function createApiClient(options) {
195
195
  filters.severity?.forEach((s) => params.append("severity", s));
196
196
  if (filters.q) params.set("q", filters.q);
197
197
  if (filters.mine) params.set("mine", "1");
198
+ if (filters.ordering) params.set("ordering", filters.ordering);
198
199
  if (filters.page && filters.page > 1) params.set("page", String(filters.page));
199
200
  const qs = params.toString();
200
201
  return qs ? `?${qs}` : "";
@@ -604,6 +605,12 @@ var DEFAULT_STRINGS = {
604
605
  "board.kpi.closed": "Closed",
605
606
  "board.kpi.rejected": "Rejected",
606
607
  "board.kpi.resolution_rate": "Resolution rate",
608
+ "board.sort": "Sort",
609
+ "board.sort.recent": "Newest first",
610
+ "board.sort.oldest": "Oldest first",
611
+ "board.sort.updated": "Recently active",
612
+ "board.sort.severity": "Severity",
613
+ "board.sort.status": "Status",
607
614
  "board.filter.status": "Status",
608
615
  "board.filter.type": "Type",
609
616
  "board.filter.severity": "Severity",
@@ -613,7 +620,8 @@ var DEFAULT_STRINGS = {
613
620
  "board.list.empty.title": "Nothing here yet",
614
621
  "board.list.empty.description": "When reports land, they\u2019ll show up here.",
615
622
  "board.list.loading": "Loading\u2026",
616
- "board.list.error": "Couldn\u2019t load reports. Try again.",
623
+ "board.list.error": "Couldn\u2019t load reports.",
624
+ "board.retry": "Try again",
617
625
  "board.list.you": "you",
618
626
  "board.list.count": "{n} of {total}",
619
627
  "board.detail.empty": "Pick a report on the left to see its full thread.",
@@ -746,6 +754,12 @@ var FRENCH_STRINGS = {
746
754
  "board.kpi.closed": "Ferm\xE9",
747
755
  "board.kpi.rejected": "Refus\xE9",
748
756
  "board.kpi.resolution_rate": "Taux de r\xE9solution",
757
+ "board.sort": "Trier",
758
+ "board.sort.recent": "Plus r\xE9cents",
759
+ "board.sort.oldest": "Plus anciens",
760
+ "board.sort.updated": "Activit\xE9 r\xE9cente",
761
+ "board.sort.severity": "S\xE9v\xE9rit\xE9",
762
+ "board.sort.status": "Statut",
749
763
  "board.filter.status": "Statut",
750
764
  "board.filter.type": "Type",
751
765
  "board.filter.severity": "S\xE9v\xE9rit\xE9",
@@ -755,7 +769,8 @@ var FRENCH_STRINGS = {
755
769
  "board.list.empty.title": "Rien \xE0 voir ici",
756
770
  "board.list.empty.description": "Les rapports appara\xEEtront ici d\xE8s qu\u2019ils arrivent.",
757
771
  "board.list.loading": "Chargement\u2026",
758
- "board.list.error": "Impossible de charger les rapports. R\xE9essayez.",
772
+ "board.list.error": "Impossible de charger les rapports.",
773
+ "board.retry": "R\xE9essayer",
759
774
  "board.list.you": "vous",
760
775
  "board.list.count": "{n} sur {total}",
761
776
  "board.detail.empty": "S\xE9lectionnez un rapport \xE0 gauche pour voir le fil complet.",
@@ -853,6 +868,25 @@ import { useCallback, useEffect as useEffect8, useState as useState7 } from "pre
853
868
  // src/widget/BoardView.tsx
854
869
  import { useEffect as useEffect2, useMemo, useState as useState2 } from "preact/hooks";
855
870
 
871
+ // src/widget/boardViewStore.ts
872
+ var PREFIX = "mhosaic.boardView.";
873
+ function loadBoardView(externalId) {
874
+ try {
875
+ const raw = localStorage.getItem(PREFIX + externalId);
876
+ if (!raw) return {};
877
+ const parsed = JSON.parse(raw);
878
+ return parsed && typeof parsed === "object" ? parsed : {};
879
+ } catch {
880
+ return {};
881
+ }
882
+ }
883
+ function saveBoardView(externalId, view) {
884
+ try {
885
+ localStorage.setItem(PREFIX + externalId, JSON.stringify(view));
886
+ } catch {
887
+ }
888
+ }
889
+
856
890
  // src/widget/ReportDetailView.tsx
857
891
  import { useEffect, useRef, useState } from "preact/hooks";
858
892
 
@@ -1291,6 +1325,7 @@ function StatusHistorySection({ rows, strings }) {
1291
1325
  // src/widget/BoardView.tsx
1292
1326
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
1293
1327
  var POLL_MS2 = 3e4;
1328
+ var SORT_OPTIONS = ["recent", "oldest", "updated", "severity", "status"];
1294
1329
  var STATUSES = [
1295
1330
  "new",
1296
1331
  "in_progress",
@@ -1301,13 +1336,17 @@ var STATUSES = [
1301
1336
  var TYPES = ["bug", "feature", "question", "praise", "typo"];
1302
1337
  var SEVERITIES = ["blocker", "high", "medium", "low"];
1303
1338
  function BoardView({ api, externalId, strings }) {
1304
- const [filters, setFilters] = useState2({});
1339
+ const [filters, setFilters] = useState2(() => loadBoardView(externalId));
1340
+ useEffect2(() => {
1341
+ saveBoardView(externalId, filters);
1342
+ }, [externalId, filtersHash(filters)]);
1305
1343
  const [page, setPage] = useState2(null);
1306
1344
  const [kpis, setKpis] = useState2(null);
1307
1345
  const [loading, setLoading] = useState2(true);
1308
1346
  const [error, setError] = useState2(null);
1309
1347
  const [selectedId, setSelectedId] = useState2(null);
1310
1348
  const [detailKey, setDetailKey] = useState2(0);
1349
+ const [reloadTick, setReloadTick] = useState2(0);
1311
1350
  const activeFilterCount = useMemo(() => {
1312
1351
  return (filters.status?.length ?? 0) + (filters.type?.length ?? 0) + (filters.severity?.length ?? 0) + (filters.q ? 1 : 0) + (filters.mine ? 1 : 0);
1313
1352
  }, [filters]);
@@ -1338,7 +1377,7 @@ function BoardView({ api, externalId, strings }) {
1338
1377
  cancelled = true;
1339
1378
  if (timer) clearTimeout(timer);
1340
1379
  };
1341
- }, [api, externalId, filtersHash(filters)]);
1380
+ }, [api, externalId, filtersHash(filters), reloadTick]);
1342
1381
  const selectedRow = useMemo(() => {
1343
1382
  if (!selectedId || !page) return null;
1344
1383
  return page.results.find((r) => r.id === selectedId) ?? null;
@@ -1360,7 +1399,22 @@ function BoardView({ api, externalId, strings }) {
1360
1399
  ),
1361
1400
  /* @__PURE__ */ jsxs3("div", { class: "board-body", children: [
1362
1401
  /* @__PURE__ */ jsxs3("div", { class: "board-list-wrap", "aria-busy": loading && !page, children: [
1363
- error && /* @__PURE__ */ jsx3("div", { class: "board-error", children: strings["board.list.error"] }),
1402
+ error && /* @__PURE__ */ jsxs3("div", { class: "board-error", role: "alert", children: [
1403
+ /* @__PURE__ */ jsx3("span", { children: strings["board.list.error"] }),
1404
+ /* @__PURE__ */ jsx3(
1405
+ "button",
1406
+ {
1407
+ type: "button",
1408
+ class: "btn btn--ghost",
1409
+ onClick: () => {
1410
+ setError(null);
1411
+ setLoading(true);
1412
+ setReloadTick((t) => t + 1);
1413
+ },
1414
+ children: strings["board.retry"]
1415
+ }
1416
+ )
1417
+ ] }),
1364
1418
  !error && loading && !page && /* @__PURE__ */ jsx3(BoardListSkeleton, {}),
1365
1419
  !error && page && page.results.length === 0 && !loading && /* @__PURE__ */ jsx3(BoardEmpty, { strings }),
1366
1420
  !error && page && page.results.length > 0 && /* @__PURE__ */ jsx3(
@@ -1477,6 +1531,7 @@ function BoardFilters({
1477
1531
  onChange({ ...filters, severity: [value] });
1478
1532
  }
1479
1533
  };
1534
+ const setOrdering = (value) => onChange({ ...filters, ordering: value });
1480
1535
  const setSearch = (q) => onChange({ ...filters, q });
1481
1536
  const toggleMine = () => {
1482
1537
  if (filters.mine) {
@@ -1489,6 +1544,16 @@ function BoardFilters({
1489
1544
  };
1490
1545
  const clear = () => onChange({});
1491
1546
  return /* @__PURE__ */ jsxs3("div", { class: "board-filters", children: [
1547
+ /* @__PURE__ */ jsx3(
1548
+ "select",
1549
+ {
1550
+ class: "board-filter-select",
1551
+ "aria-label": strings["board.sort"],
1552
+ value: filters.ordering ?? "recent",
1553
+ onChange: (e) => setOrdering(e.target.value),
1554
+ children: SORT_OPTIONS.map((o) => /* @__PURE__ */ jsx3("option", { value: o, children: strings[`board.sort.${o}`] }, o))
1555
+ }
1556
+ ),
1492
1557
  /* @__PURE__ */ jsxs3(
1493
1558
  "select",
1494
1559
  {
@@ -1652,7 +1717,8 @@ function filtersHash(f) {
1652
1717
  t: f.type?.slice().sort(),
1653
1718
  sv: f.severity?.slice().sort(),
1654
1719
  q: f.q ?? "",
1655
- m: Boolean(f.mine)
1720
+ m: Boolean(f.mine),
1721
+ o: f.ordering ?? ""
1656
1722
  });
1657
1723
  }
1658
1724
  function formatRelative(iso) {
@@ -4811,8 +4877,8 @@ function createFeedback(config) {
4811
4877
  capture_method: captureMethod,
4812
4878
  technical_context
4813
4879
  };
4814
- if ("0.19.0") {
4815
- payload.widget_version = "0.19.0";
4880
+ if ("0.20.0") {
4881
+ payload.widget_version = "0.20.0";
4816
4882
  }
4817
4883
  if (manualScreenshot) payload.screenshot = manualScreenshot;
4818
4884
  if (values.synthetic) payload.synthetic = true;
@@ -4905,4 +4971,4 @@ function createFeedback(config) {
4905
4971
  export {
4906
4972
  createFeedback
4907
4973
  };
4908
- //# sourceMappingURL=chunk-LCH5O3GT.mjs.map
4974
+ //# sourceMappingURL=chunk-YV7LMW22.mjs.map