@unhingged/vizu-core 0.1.19 → 0.1.21

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/auto.cjs CHANGED
@@ -2244,7 +2244,7 @@ var Pill = class {
2244
2244
  var Sidebar = class {
2245
2245
  constructor(root, callbacks) {
2246
2246
  this.open = false;
2247
- this.filter = "open";
2247
+ this.filter = "all";
2248
2248
  this.lastComments = [];
2249
2249
  this.lastConfidence = /* @__PURE__ */ new Map();
2250
2250
  this.handleClick = (e) => {
@@ -2264,6 +2264,7 @@ var Sidebar = class {
2264
2264
  if (f && f !== this.filter) {
2265
2265
  this.filter = f;
2266
2266
  this.render(this.lastComments);
2267
+ this.callbacks.onFilterChange?.(f);
2267
2268
  }
2268
2269
  return;
2269
2270
  }
@@ -2328,7 +2329,7 @@ var Sidebar = class {
2328
2329
  const orphans = comments.filter((c) => conf.get(c.id) === "orphaned");
2329
2330
  const anchored = comments.filter((c) => conf.get(c.id) !== "orphaned");
2330
2331
  const statusOf = (c) => c.status ?? "open";
2331
- const visible = this.filter === "open" ? anchored.filter((c) => statusOf(c) === "open") : this.filter === "resolved" ? anchored.filter((c) => statusOf(c) !== "open") : anchored;
2332
+ const visible = this.filter === "all" ? anchored : anchored.filter((c) => statusOf(c) === this.filter);
2332
2333
  const visibleOrphans = this.filter === "all" ? orphans : [];
2333
2334
  const counts = countByStatus(comments);
2334
2335
  if (visible.length === 0 && visibleOrphans.length === 0) {
@@ -2339,7 +2340,9 @@ var Sidebar = class {
2339
2340
  const closed = counts.resolved + counts.wontfix;
2340
2341
  emptyCopy = `<strong>Nothing open.</strong>${closed} closed comment${closed === 1 ? "" : "s"} hidden. Switch to <em>All</em> to see them.`;
2341
2342
  } else if (this.filter === "resolved") {
2342
- emptyCopy = `<strong>Nothing resolved.</strong>${counts.open} still open. Switch to <em>Open</em> or <em>All</em> to see more.`;
2343
+ emptyCopy = `<strong>Nothing resolved.</strong>Switch to <em>Open</em> or <em>All</em> to see more.`;
2344
+ } else if (this.filter === "wontfix") {
2345
+ emptyCopy = `<strong>Nothing marked won&apos;t&nbsp;fix.</strong>Switch to <em>Open</em> or <em>All</em> to see more.`;
2343
2346
  } else {
2344
2347
  emptyCopy = "<strong>No comments yet</strong>Click any element on the page to leave one.";
2345
2348
  }
@@ -2439,7 +2442,10 @@ var Sidebar = class {
2439
2442
  Open <span class="vz-sidebar-filter-count">${counts.open}</span>
2440
2443
  </button>
2441
2444
  <button class="vz-sidebar-filter ${this.filter === "resolved" ? "is-active" : ""}" data-vz="filter" data-filter="resolved" role="tab" aria-selected="${this.filter === "resolved"}">
2442
- Resolved <span class="vz-sidebar-filter-count">${counts.resolved + counts.wontfix}</span>
2445
+ Resolved <span class="vz-sidebar-filter-count">${counts.resolved}</span>
2446
+ </button>
2447
+ <button class="vz-sidebar-filter ${this.filter === "wontfix" ? "is-active" : ""}" data-vz="filter" data-filter="wontfix" role="tab" aria-selected="${this.filter === "wontfix"}">
2448
+ Won&apos;t fix <span class="vz-sidebar-filter-count">${counts.wontfix}</span>
2443
2449
  </button>
2444
2450
  <button class="vz-sidebar-filter ${this.filter === "all" ? "is-active" : ""}" data-vz="filter" data-filter="all" role="tab" aria-selected="${this.filter === "all"}">
2445
2451
  All <span class="vz-sidebar-filter-count">${total}</span>
@@ -3661,6 +3667,14 @@ var Vizu = class {
3661
3667
  this.selfHealedThisSession = /* @__PURE__ */ new Set();
3662
3668
  this.actions = [];
3663
3669
  this.user = null;
3670
+ /**
3671
+ * Status filter shared by the sidebar tabs and the on-page markers.
3672
+ * Picking a tab updates this (via the sidebar's onFilterChange) and
3673
+ * re-renders markers so the page shows the same subset as the panel.
3674
+ * Defaults to 'all' (matching the sidebar's default tab) — every
3675
+ * marker shows until the user narrows to a specific status.
3676
+ */
3677
+ this.statusFilter = "all";
3664
3678
  /**
3665
3679
  * Flipped true once the initial loadComments() at construction has
3666
3680
  * settled (success or failure). The cloud onAuthChanged callback uses
@@ -4192,7 +4206,11 @@ var Vizu = class {
4192
4206
  onJumpToReference: (commentId, refId2) => this.jumpToReference(commentId, refId2),
4193
4207
  onDelete: (id) => void this.removeComment(id),
4194
4208
  onUpdateStatus: (id, status) => void this.updateComment(id, { status }),
4195
- onClose: () => this.closeSidebar()
4209
+ onClose: () => this.closeSidebar(),
4210
+ onFilterChange: (filter) => {
4211
+ this.statusFilter = filter;
4212
+ this.renderAllMarkers();
4213
+ }
4196
4214
  });
4197
4215
  this.pill = new Pill(this.root, {
4198
4216
  onToggleSidebar: () => this.toggleSidebar(),
@@ -4291,6 +4309,18 @@ var Vizu = class {
4291
4309
  if (this.pendingFingerprints.length > 0) this.multiSelectMode = true;
4292
4310
  else this.multiSelectMode = false;
4293
4311
  }
4312
+ /**
4313
+ * Whether a comment (by id) matches the active status filter — the
4314
+ * marker-render counterpart of the sidebar's tab filter. 'all' matches
4315
+ * everything; the named tabs match their exact status. Unknown ids
4316
+ * (shouldn't happen) match so we never silently drop a marker.
4317
+ */
4318
+ commentMatchesStatusFilter(id) {
4319
+ if (this.statusFilter === "all") return true;
4320
+ const c = this.comments.find((x) => x.id === id);
4321
+ if (!c) return true;
4322
+ return (c.status ?? "open") === this.statusFilter;
4323
+ }
4294
4324
  commentsForElement(fp) {
4295
4325
  const key2 = fingerprintKey(fp);
4296
4326
  return this.comments.filter(
@@ -4482,6 +4512,8 @@ var Vizu = class {
4482
4512
  }
4483
4513
  for (const [key2, info] of byElement) {
4484
4514
  if (info.confidence === "orphaned" || !info.target) continue;
4515
+ const idsForFilter = info.commentIds.filter((id) => this.commentMatchesStatusFilter(id));
4516
+ if (idsForFilter.length === 0) continue;
4485
4517
  const outlineEl = document.createElement("div");
4486
4518
  outlineEl.className = "vz-comment-outline";
4487
4519
  if (info.confidence === "drifted") outlineEl.classList.add("vz-comment-outline-drifted");
@@ -4492,13 +4524,13 @@ var Vizu = class {
4492
4524
  if (info.confidence === "drifted") marker.classList.add("vz-marker-drifted");
4493
4525
  marker.setAttribute("data-element-key", key2);
4494
4526
  marker.setAttribute("data-confidence", info.confidence);
4495
- const total = info.commentIds.length;
4527
+ const total = idsForFilter.length;
4496
4528
  if (total > 1) {
4497
4529
  marker.textContent = String(total);
4498
4530
  marker.title = total + " comments";
4499
4531
  } else {
4500
4532
  marker.textContent = "";
4501
- const c = this.comments.find((c2) => c2.id === info.commentIds[0]);
4533
+ const c = this.comments.find((c2) => c2.id === idsForFilter[0]);
4502
4534
  marker.title = c?.author ? "Comment by " + c.author.name : "Comment";
4503
4535
  }
4504
4536
  marker.addEventListener("click", (e) => {
@@ -4509,9 +4541,9 @@ var Vizu = class {
4509
4541
  this.openPopoverFor([info.target], [info.fp], elComments);
4510
4542
  }
4511
4543
  });
4512
- marker.addEventListener("mouseenter", () => this.pulseRelatedElements(info.commentIds, key2));
4544
+ marker.addEventListener("mouseenter", () => this.pulseRelatedElements(idsForFilter, key2));
4513
4545
  this.root.appendChild(marker);
4514
- this.markers.set(key2, { marker, target: info.target, fp: info.fp, commentIds: info.commentIds });
4546
+ this.markers.set(key2, { marker, target: info.target, fp: info.fp, commentIds: idsForFilter });
4515
4547
  if (info.target) {
4516
4548
  this.positionMarker(marker, info.target);
4517
4549
  this.positionOutline(outlineEl, info.target);