quickdbd-cli 0.1.12__tar.gz → 0.1.13__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.
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/PKG-INFO +5 -1
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/README.md +4 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/pyproject.toml +1 -1
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/scripts/build_gallery.py +2 -2
- quickdbd_cli-0.1.13/src/quickdbd_cli/__init__.py +1 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/style.css +78 -59
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/viewer.js +1 -1
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/html.py +27 -6
- quickdbd_cli-0.1.12/src/quickdbd_cli/__init__.py +0 -1
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/.gitignore +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/LICENSE +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/NOTICE +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/examples/quickdbd-sample.txt +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/examples/synthetic/finance.txt +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/examples/synthetic/hr.txt +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/examples/synthetic/inventory.txt +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/examples/synthetic/marketing.txt +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/examples/synthetic/qdbd.layout.json +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/examples/synthetic/sales.txt +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/scripts/gen_font_metrics.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/scripts/gen_schema.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/scripts/gen_thumbnails.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/scripts/release.sh +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/__main__.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Bold.ttf +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Bold.woff2 +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-LICENSE.txt +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Regular.ttf +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Regular.woff2 +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/editor.js +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/elk-LICENSE.md +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/elk.bundled.js +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/font-metrics.json +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/render.js +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/cli.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/dbt.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/diff.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/export.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/jsrt.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/layout.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/measure.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/model.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/parser.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/project.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/serve.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/share.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/src/quickdbd_cli/tags.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/LICENSE +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/README.md +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/catalog.json +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/manifest.json +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_dbt.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_diff.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_gallery.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_parser.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_path.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_pipeline.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_select.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_serve.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_share.py +0 -0
- {quickdbd_cli-0.1.12 → quickdbd_cli-0.1.13}/tests/test_tags.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: quickdbd-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
4
4
|
Summary: Compile QuickDBD-syntax schema files into interactive HTML ER diagrams, with no table limit.
|
|
5
5
|
Project-URL: Homepage, https://github.com/MarkPhamm/quickdbd-cli
|
|
6
6
|
Author: Minh (Mark) Pham
|
|
@@ -244,6 +244,10 @@ You edit the text; the diagram is generated from it. Table positions are the one
|
|
|
244
244
|
- [Schema Diffs](https://qdbd.dev/diffs/), the [GitHub Action](https://qdbd.dev/github-action/) and the [CLI reference](https://qdbd.dev/cli/)
|
|
245
245
|
- [Development](https://qdbd.dev/development/): working on qdbd itself, releasing, and adding a demo
|
|
246
246
|
|
|
247
|
+
## About the author
|
|
248
|
+
|
|
249
|
+
qdbd is built and maintained by **Minh (Mark) Pham** ([@MarkPhamm](https://github.com/MarkPhamm)). Issues, ideas and pull requests are welcome on [GitHub](https://github.com/MarkPhamm/quickdbd-cli/issues).
|
|
250
|
+
|
|
247
251
|
## License
|
|
248
252
|
|
|
249
253
|
Apache-2.0. Bundled third-party files (ELK, Inter) and the sources of the demo schemas are listed in [NOTICE](https://github.com/MarkPhamm/quickdbd-cli/blob/main/NOTICE).
|
|
@@ -216,6 +216,10 @@ You edit the text; the diagram is generated from it. Table positions are the one
|
|
|
216
216
|
- [Schema Diffs](https://qdbd.dev/diffs/), the [GitHub Action](https://qdbd.dev/github-action/) and the [CLI reference](https://qdbd.dev/cli/)
|
|
217
217
|
- [Development](https://qdbd.dev/development/): working on qdbd itself, releasing, and adding a demo
|
|
218
218
|
|
|
219
|
+
## About the author
|
|
220
|
+
|
|
221
|
+
qdbd is built and maintained by **Minh (Mark) Pham** ([@MarkPhamm](https://github.com/MarkPhamm)). Issues, ideas and pull requests are welcome on [GitHub](https://github.com/MarkPhamm/quickdbd-cli/issues).
|
|
222
|
+
|
|
219
223
|
## License
|
|
220
224
|
|
|
221
225
|
Apache-2.0. Bundled third-party files (ELK, Inter) and the sources of the demo schemas are listed in [NOTICE](https://github.com/MarkPhamm/quickdbd-cli/blob/main/NOTICE).
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quickdbd-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.13"
|
|
8
8
|
description = "Compile QuickDBD-syntax schema files into interactive HTML ER diagrams, with no table limit."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -37,8 +37,8 @@ KINDS = ("source", "dbt", "of")
|
|
|
37
37
|
|
|
38
38
|
# Added to every demo page: a way back to the gallery, as the first item of the viewer's toolbar.
|
|
39
39
|
BACK_LINK = (
|
|
40
|
-
'<a href="../" style="color:var(--blue);
|
|
41
|
-
'font-weight:500
|
|
40
|
+
'<a href="../" style="color:var(--blue);padding:5px 9px;border-radius:6px;text-decoration:none;'
|
|
41
|
+
'font-weight:500">← All demos</a><div class="sep"></div>'
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.13"
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
--bg: #
|
|
2
|
+
--bg: #f5f6f7;
|
|
3
3
|
--blue: #2b5797;
|
|
4
|
-
--ink: #
|
|
5
|
-
--
|
|
4
|
+
--ink: #15181c;
|
|
5
|
+
--ink-2: #4a515b;
|
|
6
|
+
--muted: #6b7280;
|
|
6
7
|
--panel: #ffffff;
|
|
7
|
-
--line: #
|
|
8
|
+
--line: #e4e7eb;
|
|
9
|
+
--hover: #f1f3f5;
|
|
10
|
+
--sel: #eaf0f8;
|
|
11
|
+
--amber: #f0a020;
|
|
12
|
+
--shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 8px 24px rgba(16, 24, 40, .07);
|
|
8
13
|
}
|
|
14
|
+
::selection { background: #fde3b0; color: var(--ink); }
|
|
15
|
+
:focus-visible { outline: 2px solid var(--amber); outline-offset: 1px; }
|
|
16
|
+
* { scrollbar-width: thin; scrollbar-color: #cfd4da transparent; }
|
|
9
17
|
* { box-sizing: border-box; }
|
|
10
18
|
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
11
19
|
font-family: Inter, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; overflow: hidden; }
|
|
@@ -26,32 +34,36 @@ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
|
26
34
|
#canvas.panning .t { cursor: grabbing; }
|
|
27
35
|
|
|
28
36
|
/* toolbar (top right, like QuickDBD's zoom controls) */
|
|
29
|
-
.bar { position: absolute; top: 14px; right: 16px; display: flex; gap:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.bar button.
|
|
34
|
-
.
|
|
35
|
-
.
|
|
36
|
-
.seg
|
|
37
|
-
.
|
|
37
|
+
.bar { position: absolute; top: 14px; right: 16px; display: flex; gap: 2px; align-items: center; padding: 4px;
|
|
38
|
+
background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); z-index: 4; }
|
|
39
|
+
.bar button, .seg button { border: 0; background: transparent; color: var(--ink-2); font: inherit; font-weight: 500;
|
|
40
|
+
cursor: pointer; padding: 5px 9px; border-radius: 6px; transition: background .12s, color .12s; }
|
|
41
|
+
.bar button:hover, .seg button:hover { background: var(--hover); color: var(--ink); }
|
|
42
|
+
.bar button.on { background: var(--ink); color: #fff; }
|
|
43
|
+
.zoomval { min-width: 46px; text-align: center; color: var(--muted); font-variant-numeric: tabular-nums; }
|
|
44
|
+
.seg { display: flex; background: var(--hover); border-radius: 7px; padding: 2px; }
|
|
45
|
+
.seg button.on { background: var(--panel); color: var(--ink); box-shadow: 0 1px 2px rgba(16, 24, 40, .12); }
|
|
46
|
+
.sep { width: 1px; height: 18px; background: var(--line); margin: 0 4px; }
|
|
47
|
+
.bar button svg, .exhead button svg, .details .close svg { display: block; }
|
|
48
|
+
#zin, #zout, #zfit { padding: 5px 6px; }
|
|
38
49
|
|
|
39
50
|
/* explorer (left): search + table tree grouped by file/folder */
|
|
40
51
|
.explorer { position: absolute; top: 14px; left: 16px; width: 270px; max-height: calc(100% - 60px); display: flex;
|
|
41
|
-
flex-direction: column; background:
|
|
42
|
-
box-shadow:
|
|
52
|
+
flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
|
|
53
|
+
box-shadow: var(--shadow); z-index: 3; }
|
|
43
54
|
.exhead { display: flex; align-items: center; gap: 4px; padding: 6px; border-bottom: 1px solid var(--line); }
|
|
44
55
|
.explorer.collapsed .exhead { border-bottom: 0; }
|
|
45
|
-
.exhead button { border: 0; background: transparent; cursor: pointer; font-size: 15px; color:
|
|
46
|
-
.exhead button:hover { background:
|
|
47
|
-
.exhead input { flex: 1; min-width: 0; padding: 6px
|
|
48
|
-
background:
|
|
49
|
-
.exhead input
|
|
56
|
+
.exhead button { border: 0; background: transparent; cursor: pointer; font-size: 15px; color: var(--muted); padding: 4px 7px; border-radius: 6px; }
|
|
57
|
+
.exhead button:hover { background: var(--hover); color: var(--ink); }
|
|
58
|
+
.exhead input { flex: 1; min-width: 0; padding: 6px 9px; border: 1px solid transparent; border-radius: 7px; font: inherit;
|
|
59
|
+
background: var(--hover); color: var(--ink); outline: none; }
|
|
60
|
+
.exhead input::placeholder, .exfilter input::placeholder, .details .pathbox input::placeholder { color: var(--muted); }
|
|
61
|
+
.exhead input:focus { border-color: var(--ink-2); background: var(--panel); }
|
|
50
62
|
.exfilter { padding: 6px 6px 4px; border-bottom: 1px solid var(--line); }
|
|
51
63
|
.explorer.collapsed .exfilter { display: none; }
|
|
52
|
-
.exfilter input { width: 100%; padding: 5px 8px; border: 1px solid var(--line); border-radius:
|
|
53
|
-
outline: none; }
|
|
54
|
-
.exfilter input:focus { border-color: var(--
|
|
64
|
+
.exfilter input { width: 100%; padding: 5px 8px; border: 1px solid var(--line); border-radius: 7px; font: 12px ui-monospace, Menlo, Consolas, monospace;
|
|
65
|
+
color: var(--ink); outline: none; }
|
|
66
|
+
.exfilter input:focus { border-color: var(--ink-2); }
|
|
55
67
|
.exfilter input.bad { border-color: #e57373; }
|
|
56
68
|
.fstat { font-size: 11px; color: var(--muted); padding: 3px 2px 0; min-height: 14px; }
|
|
57
69
|
.fstat.bad { color: #c0392b; }
|
|
@@ -62,50 +74,55 @@ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
|
62
74
|
.tchip i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
|
|
63
75
|
.tchip small { color: var(--muted); }
|
|
64
76
|
.tchip:hover { border-color: #b8c2d0; }
|
|
65
|
-
.tchip.on { border-color: var(--
|
|
77
|
+
.tchip.on { border-color: var(--ink-2); background: var(--sel); }
|
|
66
78
|
.tdot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin: 0 6px 1px -13px; vertical-align: middle; }
|
|
67
79
|
.tree.flat .tdot { margin-left: 0; }
|
|
68
80
|
.details .ttags { margin: -4px 0 10px; display: flex; gap: 4px; flex-wrap: wrap; }
|
|
69
81
|
.details .ttag { color: #fff; font-size: 11px; padding: 1px 8px; border-radius: 10px; cursor: pointer; text-decoration: none; }
|
|
70
82
|
.tree { overflow: auto; padding: 4px 0 8px; }
|
|
71
83
|
.explorer.collapsed .tree { display: none; }
|
|
72
|
-
.gh { padding:
|
|
73
|
-
letter-spacing: .
|
|
74
|
-
.gh::before { content: "
|
|
75
|
-
|
|
84
|
+
.gh { padding: 8px 12px 4px; font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase;
|
|
85
|
+
letter-spacing: .05em; cursor: pointer; user-select: none; display: flex; align-items: center; justify-content: space-between; }
|
|
86
|
+
.gh::before { content: ""; width: 5px; height: 5px; margin: -2px 9px 0 2px; border-right: 1.5px solid currentColor;
|
|
87
|
+
border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform .15s; }
|
|
88
|
+
.grp.shut .gh::before { transform: rotate(-45deg); margin-top: 0; }
|
|
89
|
+
.gh:hover { color: var(--ink); }
|
|
76
90
|
.gh span { font-weight: normal; }
|
|
77
91
|
.gh .gname { flex: 1; }
|
|
78
92
|
.grp.shut .gl { display: none; }
|
|
79
93
|
.ti { padding: 4px 12px 4px 26px; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
80
94
|
.tree.flat .ti { padding-left: 14px; }
|
|
81
95
|
.ti small { color: var(--muted); margin-left: 6px; }
|
|
82
|
-
.ti:
|
|
96
|
+
.ti { border-radius: 6px; margin: 0 6px; padding-left: 20px; }
|
|
97
|
+
.ti:hover { background: var(--hover); }
|
|
98
|
+
.ti.sel { background: var(--sel); }
|
|
83
99
|
.ti.cur { color: var(--blue); font-weight: bold; }
|
|
84
100
|
.tree .empty { padding: 8px 14px; color: var(--muted); }
|
|
85
101
|
|
|
86
102
|
/* details drawer (right) */
|
|
87
|
-
.details { position: absolute; top:
|
|
88
|
-
border: 1px solid var(--line); border-radius:
|
|
103
|
+
.details { position: absolute; top: 64px; right: 16px; bottom: 16px; width: 380px; background: var(--panel);
|
|
104
|
+
border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); overflow: auto;
|
|
89
105
|
display: none; z-index: 3; padding: 16px 18px; }
|
|
90
106
|
.details.open { display: block; }
|
|
91
107
|
.has-details .minimap { right: 412px; }
|
|
92
|
-
.details .close { position: absolute; top:
|
|
93
|
-
color:
|
|
94
|
-
.details
|
|
108
|
+
.details .close { position: absolute; top: 10px; right: 10px; width: 28px; height: 28px; border: 0; border-radius: 6px;
|
|
109
|
+
background: transparent; display: flex; align-items: center; justify-content: center; color: var(--muted); cursor: pointer; }
|
|
110
|
+
.details .close:hover { background: var(--hover); color: var(--ink); }
|
|
111
|
+
.details h2 { margin: 0 28px 2px 0; font-size: 18px; font-weight: 650; letter-spacing: -.01em; color: var(--ink); word-break: break-word; }
|
|
95
112
|
.details .meta { color: var(--muted); font-size: 12px; margin-bottom: 10px; }
|
|
96
113
|
.details .doc { white-space: pre-wrap; margin: 8px 0 12px; line-height: 1.45; }
|
|
97
|
-
.details h3 { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin:
|
|
114
|
+
.details h3 { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 18px 0 6px; }
|
|
98
115
|
.details table { width: 100%; border-collapse: collapse; font-size: 12px; }
|
|
99
|
-
.details td { padding:
|
|
116
|
+
.details td { padding: 6px 4px; border-top: 1px solid var(--line); vertical-align: top; }
|
|
100
117
|
.details td.cn { font-weight: 600; word-break: break-word; }
|
|
101
|
-
.details td.ct { color:
|
|
102
|
-
.details .cd { color:
|
|
118
|
+
.details td.ct { color: var(--muted); text-align: right; white-space: nowrap; }
|
|
119
|
+
.details .cd { color: var(--ink-2); font-weight: normal; margin-top: 2px; white-space: pre-wrap; }
|
|
103
120
|
.details .tag { display: inline-block; font-size: 10px; padding: 0 5px; border-radius: 3px; background: #eef1f5;
|
|
104
121
|
color: #6b7a8c; margin: 0 3px 0 0; font-weight: normal; }
|
|
105
122
|
.details .tag.pk { background: #dfe8f6; color: var(--blue); }
|
|
106
123
|
.details .tag.fk { background: #ece6f7; color: #6a4fa3; }
|
|
107
124
|
.details ul { list-style: none; margin: 0; padding: 0; }
|
|
108
|
-
.details li { padding:
|
|
125
|
+
.details li { padding: 6px 0; border-top: 1px solid var(--line); }
|
|
109
126
|
.details a { color: var(--blue); text-decoration: none; cursor: pointer; }
|
|
110
127
|
.details a:hover { text-decoration: underline; }
|
|
111
128
|
.details .card { color: var(--muted); font-size: 11px; margin-left: 4px; }
|
|
@@ -113,22 +130,23 @@ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
|
113
130
|
.details .hidden { color: var(--muted); }
|
|
114
131
|
|
|
115
132
|
/* minimap (bottom right) */
|
|
116
|
-
.minimap { position: absolute; right: 16px; bottom: 16px; width: 200px; height: 140px; background: rgba(255,255,255
|
|
117
|
-
border: 1px solid var(--line); border-radius:
|
|
133
|
+
.minimap { position: absolute; right: 16px; bottom: 16px; width: 200px; height: 140px; background: rgba(255, 255, 255, .94);
|
|
134
|
+
border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); overflow: hidden; cursor: pointer; }
|
|
118
135
|
.minimap svg { width: 100%; height: 100%; display: block; }
|
|
119
136
|
.minimap .vpr { fill: rgba(43,87,151,.12); stroke: var(--blue); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
|
|
120
137
|
|
|
121
|
-
.toast { position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%); background:
|
|
122
|
-
padding: 8px 14px; border-radius:
|
|
138
|
+
.toast { position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%); background: var(--ink); color: #fff;
|
|
139
|
+
padding: 8px 14px; border-radius: 8px; font-size: 12px; opacity: 0; transition: opacity .2s; pointer-events: none; z-index: 6; }
|
|
123
140
|
.toast.open { opacity: 1; }
|
|
124
141
|
|
|
125
142
|
/* path finder (in the details panel) */
|
|
126
143
|
.details .pathbox { display: flex; gap: 6px; margin: 10px 0 4px; }
|
|
127
|
-
.details .pathbox input { flex: 1; min-width: 0; padding:
|
|
128
|
-
|
|
144
|
+
.details .pathbox input { flex: 1; min-width: 0; padding: 6px 9px; border: 1px solid var(--line); border-radius: 7px; font: inherit;
|
|
145
|
+
color: var(--ink); outline: none; }
|
|
146
|
+
.details .pathbox input:focus { border-color: var(--ink-2); }
|
|
129
147
|
.details .pathres ol { margin: 6px 0 8px 18px; padding: 0; }
|
|
130
148
|
.details .pathres li { border: 0; padding: 2px 0; }
|
|
131
|
-
.details .pathres pre { background:
|
|
149
|
+
.details .pathres pre { background: var(--bg); border: 1px solid var(--line); border-radius: 7px; padding: 8px; font-size: 11px;
|
|
132
150
|
overflow-x: auto; margin: 6px 0; }
|
|
133
151
|
.details .pathres .acts a { margin-right: 12px; font-size: 12px; }
|
|
134
152
|
.details .pathres .none { margin-top: 6px; }
|
|
@@ -137,8 +155,8 @@ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
|
137
155
|
.t.ph .tb { stroke: #f0a020; stroke-width: 2.5; }
|
|
138
156
|
|
|
139
157
|
/* diff banner (build --diff-base) */
|
|
140
|
-
.diffbar { position: absolute; top:
|
|
141
|
-
border-radius:
|
|
158
|
+
.diffbar { position: absolute; top: 64px; left: 50%; transform: translateX(-50%); background: var(--panel); border: 1px solid var(--line);
|
|
159
|
+
border-radius: 10px; padding: 7px 14px; font-size: 12px; box-shadow: var(--shadow); display: none; z-index: 2;
|
|
142
160
|
white-space: nowrap; }
|
|
143
161
|
.diffbar.open { display: block; }
|
|
144
162
|
.diffbar b.add { color: #2e7d32; }
|
|
@@ -155,7 +173,7 @@ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
|
155
173
|
.details .state.changed { background: #d48806; }
|
|
156
174
|
|
|
157
175
|
/* doc-comment tooltip */
|
|
158
|
-
.tip { position: absolute; display: none; max-width: 340px; background:
|
|
176
|
+
.tip { position: absolute; display: none; max-width: 340px; background: var(--ink); color: #eef0f2; border-radius: 8px;
|
|
159
177
|
padding: 8px 10px; font-size: 12px; line-height: 1.45; pointer-events: none; box-shadow: 0 4px 14px rgba(0,0,0,.25);
|
|
160
178
|
z-index: 5; }
|
|
161
179
|
.tip.open { display: block; }
|
|
@@ -166,17 +184,18 @@ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
|
166
184
|
.hint { position: absolute; left: 16px; bottom: 14px; color: var(--muted); font-size: 12px; }
|
|
167
185
|
|
|
168
186
|
/* serve: editor pane */
|
|
169
|
-
#side { width: 420px; display: flex; flex-direction: column; background: #
|
|
187
|
+
#side { width: 420px; display: flex; flex-direction: column; background: #0f1114; color: #d9dce1; border-right: 1px solid #000; }
|
|
170
188
|
#side.hidden { display: none; }
|
|
171
|
-
.tabs { display: flex; overflow-x: auto; background: #
|
|
172
|
-
.tabs button { background: transparent; color: #
|
|
173
|
-
.tabs button
|
|
189
|
+
.tabs { display: flex; overflow-x: auto; background: #08090b; border-bottom: 1px solid rgba(255, 255, 255, .08); flex: none; }
|
|
190
|
+
.tabs button { background: transparent; color: #a1a7b0; border: 0; padding: 9px 13px; font: inherit; cursor: pointer; white-space: nowrap; }
|
|
191
|
+
.tabs button:hover { color: #edeef0; }
|
|
192
|
+
.tabs button.on { color: #edeef0; background: #0f1114; box-shadow: inset 0 -2px 0 var(--amber); }
|
|
174
193
|
.tabs button .dirty { color: #f0a020; }
|
|
175
194
|
#editor { flex: 1; min-height: 0; position: relative; }
|
|
176
195
|
#editor .CodeMirror, #editor textarea { position: absolute; inset: 0; height: 100%; width: 100%; font-size: 13px;
|
|
177
|
-
font-family: Menlo, Consolas, monospace; background: #
|
|
178
|
-
#problems { height: 140px; flex: none; overflow: auto; border-top: 2px solid #
|
|
179
|
-
font-family: Menlo, Consolas, monospace; font-size: 12px; color: #
|
|
196
|
+
font-family: ui-monospace, Menlo, Consolas, monospace; background: #0f1114; color: #d9dce1; border: 0; padding: 6px; resize: none; }
|
|
197
|
+
#problems { height: 140px; flex: none; overflow: auto; border-top: 2px solid #4ade80; padding: 8px 10px; background: #08090b;
|
|
198
|
+
font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; color: #a1a7b0; }
|
|
180
199
|
#problems.bad { border-top-color: #e57373; }
|
|
181
200
|
#problems .err { color: #ff9b9b; cursor: pointer; }
|
|
182
201
|
#problems .warn { color: #f0c674; cursor: pointer; }
|
|
@@ -185,17 +204,17 @@ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
|
|
|
185
204
|
.banner button { margin-left: 8px; }
|
|
186
205
|
.cm-qdbd-op { color: #f0a020; }
|
|
187
206
|
.cm-qdbd-kw { color: #8fbcff; }
|
|
188
|
-
.CodeMirror-gutters { background: #
|
|
207
|
+
.CodeMirror-gutters { background: #0b0c0f !important; border-right: 0 !important; }
|
|
189
208
|
.cm-s-default .cm-comment { color: #7f8c8d; }
|
|
190
209
|
.cm-s-default .cm-header { color: #6fc3df; }
|
|
191
210
|
.CodeMirror-cursor { border-left-color: #fff !important; }
|
|
192
|
-
.CodeMirror-selected { background: #
|
|
211
|
+
.CodeMirror-selected { background: #2a2e35 !important; }
|
|
193
212
|
.lineerr { background: rgba(229,115,115,.18); }
|
|
194
213
|
|
|
195
214
|
/* narrow screens and embedded frames: toolbar to the bottom, smaller minimap */
|
|
196
215
|
@media (max-width: 900px) {
|
|
197
216
|
.bar { top: auto; bottom: 12px; right: auto; left: 12px; flex-wrap: wrap; max-width: calc(100% - 24px);
|
|
198
|
-
|
|
217
|
+
border-radius: 10px; padding: 3px; }
|
|
199
218
|
.hint { display: none; }
|
|
200
219
|
.minimap { width: 140px; height: 100px; bottom: auto; top: 14px; right: 12px; }
|
|
201
220
|
.explorer { max-width: calc(100% - 180px); }
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
// Keep clear of the floating search box / toolbar at the top and, on narrow screens, the toolbar at the bottom.
|
|
61
61
|
var top = 70, bottom = sz[0] < 900 ? 70 : pad, availH = sz[1] - top - bottom;
|
|
62
62
|
var k = Math.min((sz[0] - 2 * pad) / (b[2] - b[0]), availH / (b[3] - b[1]), 1.5);
|
|
63
|
-
k = Math.max(k, 0.
|
|
63
|
+
k = Math.max(k, 0.03); // same floor as manual zoom, so wide diagrams still fit a phone screen
|
|
64
64
|
S.view = { k: k, x: (sz[0] - (b[2] - b[0]) * k) / 2 - b[0] * k, y: top + (availH - (b[3] - b[1]) * k) / 2 - b[1] * k };
|
|
65
65
|
applyView();
|
|
66
66
|
}
|
|
@@ -23,6 +23,25 @@ def _escape(text: str) -> str:
|
|
|
23
23
|
return text.replace("&", "&").replace("<", "<").replace(">", ">").replace('"', """)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def _icon(d: str) -> str:
|
|
27
|
+
"""A 16px stroke icon, drawn in the toolbar's text colour."""
|
|
28
|
+
return (
|
|
29
|
+
'<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true">'
|
|
30
|
+
f'<path d="{d}" fill="none" stroke="currentColor" stroke-width="1.8"'
|
|
31
|
+
' stroke-linecap="round" stroke-linejoin="round"/>'
|
|
32
|
+
"</svg>"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
ICONS = {
|
|
37
|
+
"icon_menu": _icon("M4 6h16M4 12h16M4 18h16"),
|
|
38
|
+
"icon_close": _icon("M6 6l12 12M18 6L6 18"),
|
|
39
|
+
"icon_minus": _icon("M5 12h14"),
|
|
40
|
+
"icon_plus": _icon("M12 5v14M5 12h14"),
|
|
41
|
+
"icon_fit": _icon("M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5"),
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
26
45
|
BODY = """
|
|
27
46
|
<div id="app">
|
|
28
47
|
{side}
|
|
@@ -30,7 +49,7 @@ BODY = """
|
|
|
30
49
|
<svg id="canvas" xmlns="http://www.w3.org/2000/svg"><g id="vp"></g></svg>
|
|
31
50
|
<div class="explorer" id="explorer">
|
|
32
51
|
<div class="exhead">
|
|
33
|
-
<button id="extoggle" title="Show/hide table list"
|
|
52
|
+
<button id="extoggle" title="Show/hide table list" aria-label="Show or hide the table list">{icon_menu}</button>
|
|
34
53
|
<input id="q" type="search" placeholder="Search {count} tables ( / )" autocomplete="off" spellcheck="false">
|
|
35
54
|
</div>
|
|
36
55
|
<div class="exfilter">
|
|
@@ -42,7 +61,7 @@ BODY = """
|
|
|
42
61
|
<div id="tree" class="tree"></div>
|
|
43
62
|
</div>
|
|
44
63
|
<aside class="details" id="details" aria-label="Table details">
|
|
45
|
-
<button class="close" id="dclose" title="Close (Esc)"
|
|
64
|
+
<button class="close" id="dclose" title="Close (Esc)" aria-label="Close">{icon_close}</button>
|
|
46
65
|
<div id="dbody"></div>
|
|
47
66
|
</aside>
|
|
48
67
|
<div class="bar">
|
|
@@ -59,10 +78,10 @@ BODY = """
|
|
|
59
78
|
<button id="xpng" title="Export PNG">PNG</button>
|
|
60
79
|
<button id="xdrawio" title="Export an editable draw.io / diagrams.net file">draw.io</button>
|
|
61
80
|
<div class="sep"></div>
|
|
62
|
-
<button id="zout" title="Zoom out"
|
|
81
|
+
<button id="zout" title="Zoom out" aria-label="Zoom out">{icon_minus}</button>
|
|
63
82
|
<span class="zoomval" id="zoomval">100%</span>
|
|
64
|
-
<button id="zin" title="Zoom in"
|
|
65
|
-
<button id="zfit" title="Fit to screen"
|
|
83
|
+
<button id="zin" title="Zoom in" aria-label="Zoom in">{icon_plus}</button>
|
|
84
|
+
<button id="zfit" title="Fit to screen" aria-label="Fit to screen">{icon_fit}</button>
|
|
66
85
|
</div>
|
|
67
86
|
<div class="minimap">
|
|
68
87
|
<svg id="mini" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet"></svg>
|
|
@@ -113,7 +132,9 @@ def render_page(model: dict, positions: dict, title: str, serve: bool = False, l
|
|
|
113
132
|
hint = (
|
|
114
133
|
"Drag tables to rearrange (not saved). Click a table for details. Scroll to zoom, drag empty space to pan."
|
|
115
134
|
)
|
|
116
|
-
body = BODY.format(
|
|
135
|
+
body = BODY.format(
|
|
136
|
+
side=SIDE if serve else "", count=len(model["tables"]), hint=hint, filter_help=FILTER_HELP, **ICONS
|
|
137
|
+
)
|
|
117
138
|
head_extra = ""
|
|
118
139
|
scripts = ""
|
|
119
140
|
if serve:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.12"
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|