dbdocs 1.6.0__tar.gz → 1.6.1__tar.gz

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.
Files changed (52) hide show
  1. {dbdocs-1.6.0 → dbdocs-1.6.1}/PKG-INFO +1 -1
  2. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/css/style.css +17 -1
  3. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/js/ui.js +54 -28
  4. {dbdocs-1.6.0 → dbdocs-1.6.1}/.gitignore +0 -0
  5. {dbdocs-1.6.0 → dbdocs-1.6.1}/LICENSE +0 -0
  6. {dbdocs-1.6.0 → dbdocs-1.6.1}/README.md +0 -0
  7. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/__init__.py +0 -0
  8. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/__main__.py +0 -0
  9. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/cli/__init__.py +0 -0
  10. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/cli/main.py +0 -0
  11. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/core/__init__.py +0 -0
  12. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/core/artifacts.py +0 -0
  13. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/core/config.py +0 -0
  14. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/core/exceptions.py +0 -0
  15. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/core/log.py +0 -0
  16. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/__init__.py +0 -0
  17. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/_sqlglot_lineage.py +0 -0
  18. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/column_lineage.py +0 -0
  19. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/erd.py +0 -0
  20. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/graph.py +0 -0
  21. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/__init__.py +0 -0
  22. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/dimensions.py +0 -0
  23. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/extractor.py +0 -0
  24. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/__init__.py +0 -0
  25. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/base.py +0 -0
  26. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/dimensions/__init__.py +0 -0
  27. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/dimensions/documentation.py +0 -0
  28. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/dimensions/governance.py +0 -0
  29. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/dimensions/modeling.py +0 -0
  30. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/dimensions/performance.py +0 -0
  31. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/dimensions/structure.py +0 -0
  32. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/dimensions/testing.py +0 -0
  33. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/health/rules/registry.py +0 -0
  34. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/nodes.py +0 -0
  35. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/extract/tests_index.py +0 -0
  36. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/main.py +0 -0
  37. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/__init__.py +0 -0
  38. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/api_schema.py +0 -0
  39. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/builder.py +0 -0
  40. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/css/icons.css +0 -0
  41. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/favicon.svg +0 -0
  42. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/graph/index.css +0 -0
  43. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/graph/index.js +0 -0
  44. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/js/app.js +0 -0
  45. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/js/data.js +0 -0
  46. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/js/service.js +0 -0
  47. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/vendor/marked.min.js +0 -0
  48. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/assets/vendor/minisearch.min.js +0 -0
  49. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/bundle/index.html +0 -0
  50. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/deploy.py +0 -0
  51. {dbdocs-1.6.0 → dbdocs-1.6.1}/dbdocs/site/inject.py +0 -0
  52. {dbdocs-1.6.0 → dbdocs-1.6.1}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbdocs
3
- Version: 1.6.0
3
+ Version: 1.6.1
4
4
  Summary: Alternative dbt docs site: Catalog + ERD + column-level lineage
5
5
  Project-URL: Homepage, https://github.com/datnguye/dbt-docs
6
6
  Project-URL: Repository, https://github.com/datnguye/dbt-docs
@@ -411,6 +411,13 @@ details.node-section > summary.node-section-summary:hover .node-section-title {
411
411
  .node-section-summary-actions {
412
412
  display: inline-flex; align-items: center; gap: 6px; margin-left: auto; flex-shrink: 0;
413
413
  }
414
+ /* Per-section copy-link anchor: icon-only, fades in on summary hover/focus. */
415
+ .section-link-btn { padding: 4px 7px; opacity: 0; transition: opacity 0.15s, border-color 0.15s, color 0.15s; }
416
+ details.node-section > summary.node-section-summary:hover .section-link-btn,
417
+ details.node-section > summary.node-section-summary:focus-within .section-link-btn,
418
+ .section-link-btn:focus-visible { opacity: 1; }
419
+ .section-link-btn.copied { opacity: 1; border-color: var(--accent); color: var(--accent); }
420
+ @media print { .section-link-btn { display: none; } }
414
421
  .node-section-body { padding: 4px 0 20px 18px; }
415
422
  /* Section divider: last section needs no bottom border */
416
423
  details.node-section:last-of-type { border-bottom: none; }
@@ -578,11 +585,20 @@ details.health-section > summary:hover .health-section-title { text-decoration:
578
585
  padding: 10px 14px; border-radius: var(--radius); border: 1px solid var(--border);
579
586
  background: var(--bg-soft); text-decoration: none; color: inherit;
580
587
  border-left-width: 4px;
588
+ transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
581
589
  }
582
590
  /* Narrow viewports: wrap to fewer columns rather than squeezing six. */
583
591
  @media (max-width: 900px) { .health-scorecard { grid-template-columns: repeat(3, 1fr); } }
584
592
  @media (max-width: 560px) { .health-scorecard { grid-template-columns: repeat(2, 1fr); } }
585
- a.score-chip:hover { background: var(--bg-elev); }
593
+ /* Modern clickable-card affordance: lift + accent border, no link underline.
594
+ The status-colored left edge is preserved (only the other three sides accent). */
595
+ a.score-chip:hover {
596
+ text-decoration: none; transform: translateY(-2px); box-shadow: var(--shadow);
597
+ border-top-color: var(--accent); border-right-color: var(--accent); border-bottom-color: var(--accent);
598
+ }
599
+ a.score-chip:hover .score-name { text-decoration: none; }
600
+ a.score-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
601
+ @media (prefers-reduced-motion: reduce) { .score-chip { transition: none; } a.score-chip:hover { transform: none; } }
586
602
  .score-chip.good { border-left-color: var(--score-good); }
587
603
  .score-chip.warn { border-left-color: var(--score-warn); }
588
604
  .score-chip.bad { border-left-color: var(--score-bad); }
@@ -61,11 +61,21 @@ function graphMount(mode, focus, rtype, schema, erdFocus, erdSchema, layer) {
61
61
  return root;
62
62
  }
63
63
 
64
+ /* Copy text to the clipboard, invoking onResult(ok) once. Guards the absent
65
+ clipboard API (insecure context / old browser) → onResult(false). Shared by
66
+ every copy-link affordance so the plumbing lives in one place. */
67
+ function copyToClipboard(text, onResult) {
68
+ if (navigator.clipboard && navigator.clipboard.writeText) {
69
+ navigator.clipboard.writeText(text).then(function () { onResult(true); }).catch(function () { onResult(false); });
70
+ } else {
71
+ onResult(false);
72
+ }
73
+ }
74
+
64
75
  function copyLinkButton() {
65
76
  var btn = el("button", { class: "fs-btn copy-link-btn", type: "button", title: "Copy link to this page" });
66
77
  btn.appendChild(icon("link", 15));
67
78
  btn.appendChild(document.createTextNode(" Copy link"));
68
- // Flash a transient label (and the .copied accent on success), then reset.
69
79
  function flash(label, ok) {
70
80
  btn.lastChild.textContent = label;
71
81
  btn.classList.toggle("copied", !!ok);
@@ -75,15 +85,28 @@ function copyLinkButton() {
75
85
  }, 1800);
76
86
  }
77
87
  btn.addEventListener("click", function () {
78
- if (navigator.clipboard && navigator.clipboard.writeText) {
79
- navigator.clipboard.writeText(location.href).then(function () {
80
- flash(" Copied!", true);
81
- }).catch(function () {
82
- flash(" Copy unavailable", false);
83
- });
84
- } else {
85
- flash(" Copy unavailable", false);
86
- }
88
+ copyToClipboard(location.href, function (ok) { flash(ok ? " Copied!" : " Copy unavailable", ok); });
89
+ });
90
+ return btn;
91
+ }
92
+
93
+ /* Copy-link anchor for an individual node-page section. Copies a deep link
94
+ (#/node/<id>?sec=<sectionId>) that route() resolves via focusSection — opening
95
+ and scrolling to this section on load. Lives in the summary's actions slot. */
96
+ function sectionLinkButton(nodeId, sectionId) {
97
+ var btn = el("button", {
98
+ class: "fs-btn section-link-btn", type: "button",
99
+ title: "Copy link to this section", "aria-label": "Copy link to this section",
100
+ });
101
+ btn.appendChild(icon("link", 14));
102
+ function flash(ok) {
103
+ btn.classList.toggle("copied", !!ok);
104
+ setTimeout(function () { btn.classList.remove("copied"); }, 1800);
105
+ }
106
+ btn.addEventListener("click", function () {
107
+ var url = location.origin + location.pathname +
108
+ "#/node/" + encodeURIComponent(nodeId) + "?sec=" + encodeURIComponent(sectionId);
109
+ copyToClipboard(url, flash);
87
110
  });
88
111
  return btn;
89
112
  }
@@ -502,27 +525,29 @@ function healthSummaryCard() {
502
525
  section.appendChild(el("p", { class: "muted health-card-sub" }, [
503
526
  total === 0 ? "No issues detected." : String(total) + " issue" + (total !== 1 ? "s" : "") + " across " + dims.length + " dimensions.",
504
527
  ]));
505
- section.appendChild(healthScorecard(true, dims));
528
+ section.appendChild(healthScorecard(dims));
506
529
  return section;
507
530
  }
508
531
 
509
- /* The scorecard: one chip per dimension with its score% + issue count. When
510
- *compact* the chips link to the dimension's section on the Health page.
511
- *dims* may be passed to avoid recomputing the dimension list. */
512
- function healthScorecard(compact, dims) {
513
- var chips = (dims || svc.healthDimensions()).map(function (d) {
514
- // Dimension name on top, then the score %, then the issue count.
532
+ /* The scorecard: one card per dimension with its score% + issue count. Each card
533
+ deep-links to its dimension's section via "#/health?d=<key>" — on the overview
534
+ that navigates to the Health page; on the Health page it re-routes and scrolls
535
+ to (and opens) the section. *dims* may be passed to avoid recomputing the list. */
536
+ function healthScorecard(dims) {
537
+ var cards = (dims || svc.healthDimensions()).map(function (d) {
538
+ var label = HEALTH_DIM_LABELS[d.key] || healthLabel(d.key);
515
539
  var children = [
516
- el("span", { class: "score-name" }, [HEALTH_DIM_LABELS[d.key] || healthLabel(d.key)]),
540
+ el("span", { class: "score-name" }, [label]),
517
541
  el("span", { class: "score-num" }, [String(d.score), el("span", { class: "score-pct" }, ["%"])]),
518
542
  el("span", { class: "score-issues muted" }, [d.issues === 0 ? "clear" : String(d.issues) + " issue" + (d.issues !== 1 ? "s" : "")]),
519
543
  ];
520
- var attrs = { class: "score-chip " + healthScoreClass(d.score) };
521
- // On the overview card, each chip deep-links to its dimension's section.
522
- if (compact) { attrs.href = "#/health?d=" + encodeURIComponent(d.key); return el("a", attrs, children); }
523
- return el("div", attrs, children);
544
+ return el("a", {
545
+ class: "score-chip " + healthScoreClass(d.score),
546
+ href: "#/health?d=" + encodeURIComponent(d.key),
547
+ "aria-label": label + ": " + d.score + "%, " + (d.issues === 0 ? "no issues" : d.issues + " issue" + (d.issues !== 1 ? "s" : "")),
548
+ }, children);
524
549
  });
525
- return el("div", { class: "health-scorecard" }, chips);
550
+ return el("div", { class: "health-scorecard" }, cards);
526
551
  }
527
552
 
528
553
  /* Health Check page — scorecard + one collapsible section per dimension. When
@@ -541,7 +566,7 @@ function renderHealth(focusDim) {
541
566
  " dimensions, derived from your dbt artifacts.",
542
567
  ]));
543
568
 
544
- app.appendChild(healthScorecard(false));
569
+ app.appendChild(healthScorecard());
545
570
 
546
571
  var note = svc.healthNote();
547
572
  if (note) app.appendChild(el("p", { class: "empty health-note" }, [note]));
@@ -896,8 +921,9 @@ function nodeSection(opts) {
896
921
  if (opts.count != null) {
897
922
  summaryChildren.push(el("span", { class: "node-section-count" }, [String(opts.count)]));
898
923
  }
899
- if (opts.actions) {
900
- var actionList = Array.isArray(opts.actions) ? opts.actions : [opts.actions];
924
+ var actionList = opts.actions ? (Array.isArray(opts.actions) ? opts.actions.slice() : [opts.actions]) : [];
925
+ if (nodeId && sectionId) actionList.unshift(sectionLinkButton(nodeId, sectionId));
926
+ if (actionList.length) {
901
927
  var actionsWrap = el("span", { class: "node-section-summary-actions" });
902
928
  actionList.forEach(function (a) {
903
929
  a.addEventListener("click", function (e) { e.stopPropagation(); });
@@ -1056,8 +1082,6 @@ function renderPhysicalNode(n) {
1056
1082
  var detSec = _physicalDetailsSection(n);
1057
1083
  if (detSec) app.appendChild(detSec);
1058
1084
 
1059
- _appendDepsSections(n);
1060
-
1061
1085
  app.appendChild(_columnsSection(n));
1062
1086
 
1063
1087
  var testSec = _testsSection(n);
@@ -1065,6 +1089,8 @@ function renderPhysicalNode(n) {
1065
1089
 
1066
1090
  app.appendChild(_erdSection(n));
1067
1091
 
1092
+ _appendDepsSections(n);
1093
+
1068
1094
  var sqlSec = _sqlSection(n);
1069
1095
  if (sqlSec) app.appendChild(sqlSec);
1070
1096
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes