quickdbd-cli 0.1.11__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.11 → quickdbd_cli-0.1.13}/PKG-INFO +20 -16
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/README.md +19 -15
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/pyproject.toml +2 -2
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/scripts/build_gallery.py +3 -3
- quickdbd_cli-0.1.13/src/quickdbd_cli/__init__.py +1 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/style.css +78 -59
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/viewer.js +1 -1
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/html.py +27 -6
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_gallery.py +2 -0
- quickdbd_cli-0.1.11/gallery/adventureworks/LICENSE +0 -25
- quickdbd_cli-0.1.11/gallery/chinook/LICENSE +0 -11
- quickdbd_cli-0.1.11/gallery/northwind/LICENSE +0 -25
- quickdbd_cli-0.1.11/gallery/sakila/LICENSE +0 -29
- quickdbd_cli-0.1.11/gallery/shopify/LICENSE +0 -201
- quickdbd_cli-0.1.11/gallery/shopify/README.md +0 -10
- quickdbd_cli-0.1.11/gallery/synthea/LICENSE +0 -201
- quickdbd_cli-0.1.11/gallery/synthea/README.md +0 -7
- quickdbd_cli-0.1.11/src/quickdbd_cli/__init__.py +0 -1
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/.gitignore +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/LICENSE +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/NOTICE +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/examples/quickdbd-sample.txt +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/examples/synthetic/finance.txt +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/examples/synthetic/hr.txt +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/examples/synthetic/inventory.txt +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/examples/synthetic/marketing.txt +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/examples/synthetic/qdbd.layout.json +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/examples/synthetic/sales.txt +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/scripts/gen_font_metrics.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/scripts/gen_schema.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/scripts/gen_thumbnails.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/scripts/release.sh +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/__main__.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Bold.ttf +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Bold.woff2 +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-LICENSE.txt +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Regular.ttf +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/Inter-Regular.woff2 +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/editor.js +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/elk-LICENSE.md +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/elk.bundled.js +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/font-metrics.json +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/assets/render.js +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/cli.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/dbt.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/diff.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/export.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/jsrt.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/layout.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/measure.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/model.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/parser.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/project.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/serve.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/share.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/src/quickdbd_cli/tags.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/LICENSE +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/README.md +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/catalog.json +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/fixtures/jaffle/manifest.json +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_dbt.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_diff.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_parser.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_path.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_pipeline.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_select.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_serve.py +0 -0
- {quickdbd_cli-0.1.11 → quickdbd_cli-0.1.13}/tests/test_share.py +0 -0
- {quickdbd_cli-0.1.11 → 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
|
|
@@ -36,14 +36,14 @@ Description-Content-Type: text/markdown
|
|
|
36
36
|
<p align="center"><b>Interactive ER diagrams from QuickDBD text or a dbt project, readable at 200+ tables</b></p>
|
|
37
37
|
|
|
38
38
|
<p align="center">
|
|
39
|
-
<a href="https://
|
|
39
|
+
<a href="https://qdbd.dev/">Docs</a> · <a href="https://qdbd.dev/demo/">Live demos</a> · <a href="#quickstart">Quickstart</a> · <a href="https://pypi.org/project/quickdbd-cli/">PyPI</a>
|
|
40
40
|
</p>
|
|
41
41
|
|
|
42
42
|
<p align="center">
|
|
43
|
-
<a href="https://
|
|
43
|
+
<a href="https://qdbd.dev/demo/adventureworks/#t=SalesOrderHeader"><img src="https://raw.githubusercontent.com/MarkPhamm/quickdbd-cli/main/docs/assets/img/hero.png" alt="The AdventureWorks sample database as a qdbd diagram, with the SalesOrderHeader table selected" width="760"></a>
|
|
44
44
|
</p>
|
|
45
45
|
<p align="center">
|
|
46
|
-
<em>AdventureWorks (68 tables) with its column descriptions, built by qdbd. <a href="https://
|
|
46
|
+
<em>AdventureWorks (68 tables) with its column descriptions, built by qdbd. <a href="https://qdbd.dev/demo/adventureworks/#t=SalesOrderHeader">Try it live →</a></em>
|
|
47
47
|
</p>
|
|
48
48
|
|
|
49
49
|
## What is qdbd?
|
|
@@ -74,10 +74,10 @@ Every demo is a single HTML page written by `qdbd build`, from a QuickDBD schema
|
|
|
74
74
|
<!-- gallery:start: generated by `python scripts/build_gallery.py --readme` from gallery/demos.toml -->
|
|
75
75
|
| | |
|
|
76
76
|
|---|---|
|
|
77
|
-
| [](https://
|
|
78
|
-
| [](https://
|
|
77
|
+
| [](https://qdbd.dev/demo/synthetic/)<br>**[200 tables](https://qdbd.dev/demo/synthetic/)**<br>Five business domains, 200 tables and every relationship type. Search, filter, click a table to focus it. | [](https://qdbd.dev/demo/diff/)<br>**[Schema diff](https://qdbd.dev/demo/diff/)**<br>What a branch changed, coloured in: new tables in green, changed columns in amber, removals listed. |
|
|
78
|
+
| [](https://qdbd.dev/demo/adventureworks/)<br>**[AdventureWorks](https://qdbd.dev/demo/adventureworks/)**<br>Microsoft's bicycle-company OLTP database: 68 tables in five schemas, one region each, with column descriptions. | [](https://qdbd.dev/demo/synthea/#t=concept)<br>**[OMOP CDM on Synthea](https://qdbd.dev/demo/synthea/#t=concept)**<br>OHDSI's dbt-synthea: synthetic patient records mapped to the OMOP Common Data Model. 145 tables, 235 relationships from tests. |
|
|
79
79
|
|
|
80
|
-
[View all 14 demos →](https://
|
|
80
|
+
[View all 14 demos →](https://qdbd.dev/demo/)
|
|
81
81
|
<!-- gallery:end -->
|
|
82
82
|
|
|
83
83
|
## Quickstart
|
|
@@ -99,7 +99,7 @@ A browser tab opens with the diagram and an editor. Change the text and the diag
|
|
|
99
99
|
pipx install quickdbd-cli # or: pip install quickdbd-cli / uv tool install quickdbd-cli
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
Python 3.11+. See [Install](https://
|
|
102
|
+
Python 3.11+. See [Install](https://qdbd.dev/install/) for other options.
|
|
103
103
|
|
|
104
104
|
#### 2. Write a schema, or generate one from dbt
|
|
105
105
|
|
|
@@ -118,7 +118,7 @@ CustomerId int FK >- Customer.CustomerId
|
|
|
118
118
|
Total decimal(10,2)
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
A table is a name, a line of dashes, then one column per line. `FK >- Customer.CustomerId` means many orders to one customer. The full syntax is in [Schema Syntax](https://
|
|
121
|
+
A table is a name, a line of dashes, then one column per line. `FK >- Customer.CustomerId` means many orders to one customer. The full syntax is in [Schema Syntax](https://qdbd.dev/syntax/).
|
|
122
122
|
|
|
123
123
|
For a dbt project, generate the schema instead:
|
|
124
124
|
|
|
@@ -163,7 +163,7 @@ jobs:
|
|
|
163
163
|
output: site/index.html
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
dbt projects, GitHub Pages, pre-commit and GitLab CI are covered in [CI and Automation](https://
|
|
166
|
+
dbt projects, GitHub Pages, pre-commit and GitLab CI are covered in [CI and Automation](https://qdbd.dev/github-action/).
|
|
167
167
|
|
|
168
168
|
## How qdbd works
|
|
169
169
|
|
|
@@ -237,12 +237,16 @@ You edit the text; the diagram is generated from it. Table positions are the one
|
|
|
237
237
|
|
|
238
238
|
## Learn more
|
|
239
239
|
|
|
240
|
-
- [Install](https://
|
|
241
|
-
- [Schema Syntax](https://
|
|
242
|
-
- [Reading the Diagram](https://
|
|
243
|
-
- [dbt Projects](https://
|
|
244
|
-
- [Schema Diffs](https://
|
|
245
|
-
- [Development](https://
|
|
240
|
+
- [Install](https://qdbd.dev/install/) and [Quick Start](https://qdbd.dev/getting-started/)
|
|
241
|
+
- [Schema Syntax](https://qdbd.dev/syntax/), [many files](https://qdbd.dev/files/), [table positions](https://qdbd.dev/layout/), [tags and colours](https://qdbd.dev/tags/)
|
|
242
|
+
- [Reading the Diagram](https://qdbd.dev/reading-the-diagram/), [selectors](https://qdbd.dev/selectors/), [exports](https://qdbd.dev/exports/), [sharing a link](https://qdbd.dev/sharing/)
|
|
243
|
+
- [dbt Projects](https://qdbd.dev/dbt/), with a [jaffle_shop walkthrough](https://qdbd.dev/example/)
|
|
244
|
+
- [Schema Diffs](https://qdbd.dev/diffs/), the [GitHub Action](https://qdbd.dev/github-action/) and the [CLI reference](https://qdbd.dev/cli/)
|
|
245
|
+
- [Development](https://qdbd.dev/development/): working on qdbd itself, releasing, and adding a demo
|
|
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).
|
|
246
250
|
|
|
247
251
|
## License
|
|
248
252
|
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
<p align="center"><b>Interactive ER diagrams from QuickDBD text or a dbt project, readable at 200+ tables</b></p>
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
|
-
<a href="https://
|
|
11
|
+
<a href="https://qdbd.dev/">Docs</a> · <a href="https://qdbd.dev/demo/">Live demos</a> · <a href="#quickstart">Quickstart</a> · <a href="https://pypi.org/project/quickdbd-cli/">PyPI</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
|
-
<a href="https://
|
|
15
|
+
<a href="https://qdbd.dev/demo/adventureworks/#t=SalesOrderHeader"><img src="https://raw.githubusercontent.com/MarkPhamm/quickdbd-cli/main/docs/assets/img/hero.png" alt="The AdventureWorks sample database as a qdbd diagram, with the SalesOrderHeader table selected" width="760"></a>
|
|
16
16
|
</p>
|
|
17
17
|
<p align="center">
|
|
18
|
-
<em>AdventureWorks (68 tables) with its column descriptions, built by qdbd. <a href="https://
|
|
18
|
+
<em>AdventureWorks (68 tables) with its column descriptions, built by qdbd. <a href="https://qdbd.dev/demo/adventureworks/#t=SalesOrderHeader">Try it live →</a></em>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
21
|
## What is qdbd?
|
|
@@ -46,10 +46,10 @@ Every demo is a single HTML page written by `qdbd build`, from a QuickDBD schema
|
|
|
46
46
|
<!-- gallery:start: generated by `python scripts/build_gallery.py --readme` from gallery/demos.toml -->
|
|
47
47
|
| | |
|
|
48
48
|
|---|---|
|
|
49
|
-
| [](https://
|
|
50
|
-
| [](https://
|
|
49
|
+
| [](https://qdbd.dev/demo/synthetic/)<br>**[200 tables](https://qdbd.dev/demo/synthetic/)**<br>Five business domains, 200 tables and every relationship type. Search, filter, click a table to focus it. | [](https://qdbd.dev/demo/diff/)<br>**[Schema diff](https://qdbd.dev/demo/diff/)**<br>What a branch changed, coloured in: new tables in green, changed columns in amber, removals listed. |
|
|
50
|
+
| [](https://qdbd.dev/demo/adventureworks/)<br>**[AdventureWorks](https://qdbd.dev/demo/adventureworks/)**<br>Microsoft's bicycle-company OLTP database: 68 tables in five schemas, one region each, with column descriptions. | [](https://qdbd.dev/demo/synthea/#t=concept)<br>**[OMOP CDM on Synthea](https://qdbd.dev/demo/synthea/#t=concept)**<br>OHDSI's dbt-synthea: synthetic patient records mapped to the OMOP Common Data Model. 145 tables, 235 relationships from tests. |
|
|
51
51
|
|
|
52
|
-
[View all 14 demos →](https://
|
|
52
|
+
[View all 14 demos →](https://qdbd.dev/demo/)
|
|
53
53
|
<!-- gallery:end -->
|
|
54
54
|
|
|
55
55
|
## Quickstart
|
|
@@ -71,7 +71,7 @@ A browser tab opens with the diagram and an editor. Change the text and the diag
|
|
|
71
71
|
pipx install quickdbd-cli # or: pip install quickdbd-cli / uv tool install quickdbd-cli
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
Python 3.11+. See [Install](https://
|
|
74
|
+
Python 3.11+. See [Install](https://qdbd.dev/install/) for other options.
|
|
75
75
|
|
|
76
76
|
#### 2. Write a schema, or generate one from dbt
|
|
77
77
|
|
|
@@ -90,7 +90,7 @@ CustomerId int FK >- Customer.CustomerId
|
|
|
90
90
|
Total decimal(10,2)
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
A table is a name, a line of dashes, then one column per line. `FK >- Customer.CustomerId` means many orders to one customer. The full syntax is in [Schema Syntax](https://
|
|
93
|
+
A table is a name, a line of dashes, then one column per line. `FK >- Customer.CustomerId` means many orders to one customer. The full syntax is in [Schema Syntax](https://qdbd.dev/syntax/).
|
|
94
94
|
|
|
95
95
|
For a dbt project, generate the schema instead:
|
|
96
96
|
|
|
@@ -135,7 +135,7 @@ jobs:
|
|
|
135
135
|
output: site/index.html
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
dbt projects, GitHub Pages, pre-commit and GitLab CI are covered in [CI and Automation](https://
|
|
138
|
+
dbt projects, GitHub Pages, pre-commit and GitLab CI are covered in [CI and Automation](https://qdbd.dev/github-action/).
|
|
139
139
|
|
|
140
140
|
## How qdbd works
|
|
141
141
|
|
|
@@ -209,12 +209,16 @@ You edit the text; the diagram is generated from it. Table positions are the one
|
|
|
209
209
|
|
|
210
210
|
## Learn more
|
|
211
211
|
|
|
212
|
-
- [Install](https://
|
|
213
|
-
- [Schema Syntax](https://
|
|
214
|
-
- [Reading the Diagram](https://
|
|
215
|
-
- [dbt Projects](https://
|
|
216
|
-
- [Schema Diffs](https://
|
|
217
|
-
- [Development](https://
|
|
212
|
+
- [Install](https://qdbd.dev/install/) and [Quick Start](https://qdbd.dev/getting-started/)
|
|
213
|
+
- [Schema Syntax](https://qdbd.dev/syntax/), [many files](https://qdbd.dev/files/), [table positions](https://qdbd.dev/layout/), [tags and colours](https://qdbd.dev/tags/)
|
|
214
|
+
- [Reading the Diagram](https://qdbd.dev/reading-the-diagram/), [selectors](https://qdbd.dev/selectors/), [exports](https://qdbd.dev/exports/), [sharing a link](https://qdbd.dev/sharing/)
|
|
215
|
+
- [dbt Projects](https://qdbd.dev/dbt/), with a [jaffle_shop walkthrough](https://qdbd.dev/example/)
|
|
216
|
+
- [Schema Diffs](https://qdbd.dev/diffs/), the [GitHub Action](https://qdbd.dev/github-action/) and the [CLI reference](https://qdbd.dev/cli/)
|
|
217
|
+
- [Development](https://qdbd.dev/development/): working on qdbd itself, releasing, and adding a demo
|
|
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).
|
|
218
222
|
|
|
219
223
|
## License
|
|
220
224
|
|
|
@@ -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,7 +37,7 @@ Homepage = "https://github.com/MarkPhamm/quickdbd-cli"
|
|
|
37
37
|
packages = ["src/quickdbd_cli"]
|
|
38
38
|
|
|
39
39
|
[tool.hatch.build.targets.sdist]
|
|
40
|
-
include = ["src", "tests", "examples", "scripts", "README.md", "LICENSE", "NOTICE"]
|
|
40
|
+
include = ["src", "tests", "examples", "scripts", "/README.md", "/LICENSE", "/NOTICE"]
|
|
41
41
|
|
|
42
42
|
[tool.ruff]
|
|
43
43
|
line-length = 120
|
|
@@ -27,7 +27,7 @@ ROOT = Path(__file__).resolve().parent.parent
|
|
|
27
27
|
CATALOG = ROOT / "gallery" / "demos.toml"
|
|
28
28
|
TEMPLATE = ROOT / "gallery" / "index.html"
|
|
29
29
|
README = ROOT / "README.md"
|
|
30
|
-
SITE = "https://
|
|
30
|
+
SITE = "https://qdbd.dev/demo/"
|
|
31
31
|
RAW = "https://raw.githubusercontent.com/MarkPhamm/quickdbd-cli/main/docs/assets/img/"
|
|
32
32
|
README_START = "<!-- gallery:start: generated by `python scripts/build_gallery.py --readme` from gallery/demos.toml -->"
|
|
33
33
|
README_END = "<!-- gallery:end -->"
|
|
@@ -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:
|
|
@@ -8,6 +8,8 @@ from pathlib import Path
|
|
|
8
8
|
import pytest
|
|
9
9
|
|
|
10
10
|
ROOT = Path(__file__).resolve().parent.parent
|
|
11
|
+
if not (ROOT / "gallery" / "demos.toml").exists(): # the sdist ships tests but not the gallery
|
|
12
|
+
pytest.skip("needs the git checkout's gallery/", allow_module_level=True)
|
|
11
13
|
sys.path.insert(0, str(ROOT / "scripts"))
|
|
12
14
|
|
|
13
15
|
import build_gallery # noqa: E402
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
Microsoft SQL Server Sample Code
|
|
2
|
-
|
|
3
|
-
Copyright (c) Microsoft Corporation
|
|
4
|
-
|
|
5
|
-
All rights reserved.
|
|
6
|
-
|
|
7
|
-
MIT License.
|
|
8
|
-
|
|
9
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
-
in the Software without restriction, including without limitation the rights
|
|
12
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
-
furnished to do so, subject to the following conditions:
|
|
15
|
-
|
|
16
|
-
The above copyright notice and this permission notice shall be included in
|
|
17
|
-
all copies or substantial portions of the Software.
|
|
18
|
-
|
|
19
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
25
|
-
THE SOFTWARE.
|