fastapi-voyager 0.7.2__tar.gz → 0.7.4__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.
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/PKG-INFO +6 -1
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/README.md +5 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/render.py +38 -28
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/version.py +1 -1
- fastapi_voyager-0.7.4/src/fastapi_voyager/web/index.html +383 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/vue-main.js +52 -1
- fastapi_voyager-0.7.2/src/fastapi_voyager/web/index.html +0 -288
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/.gitignore +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/.python-version +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/LICENSE +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/pyproject.toml +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/__init__.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/cli.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/filter.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/module.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/server.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/type.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/type_helper.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/voyager.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/component/render-graph.js +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/component/route-code-display.js +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/component/schema-code-display.js +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/component/schema-field-filter.js +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/graph-ui.js +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/quasar.min.css +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/quasar.min.js +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/__init__.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/demo.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/demo_anno.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/programatic.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/service/__init__.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/service/schema.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/test_analysis.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/test_filter.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/test_generic.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/test_import.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/test_module.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/tests/test_type_helper.py +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/uv.lock +0 -0
- {fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/voyager.jpg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-voyager
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.4
|
|
4
4
|
Summary: Visualize FastAPI application's routing tree and dependencies
|
|
5
5
|
Project-URL: Homepage, https://github.com/allmonday/fastapi-voyager
|
|
6
6
|
Project-URL: Source, https://github.com/allmonday/fastapi-voyager
|
|
@@ -204,6 +204,11 @@ TODO: ...
|
|
|
204
204
|
## Changelog
|
|
205
205
|
|
|
206
206
|
- 0.7:
|
|
207
|
+
- 0.7.4
|
|
208
|
+
- optimize tag/route, move to left.
|
|
209
|
+
- fresh on change, no need to click generate any more.
|
|
210
|
+
- 0.7.3
|
|
211
|
+
- fix `module_color` failure
|
|
207
212
|
- 0.7.2
|
|
208
213
|
- keep links inside filtered nodes.
|
|
209
214
|
- 0.7.1
|
|
@@ -177,6 +177,11 @@ TODO: ...
|
|
|
177
177
|
## Changelog
|
|
178
178
|
|
|
179
179
|
- 0.7:
|
|
180
|
+
- 0.7.4
|
|
181
|
+
- optimize tag/route, move to left.
|
|
182
|
+
- fresh on change, no need to click generate any more.
|
|
183
|
+
- 0.7.3
|
|
184
|
+
- fix `module_color` failure
|
|
180
185
|
- 0.7.2
|
|
181
186
|
- keep links inside filtered nodes.
|
|
182
187
|
- 0.7.1
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from fastapi_voyager.type import SchemaNode, ModuleNode, Link, Tag, Route, FieldType, PK, ModuleRoute
|
|
2
3
|
from fastapi_voyager.module import build_module_schema_tree, build_module_route_tree
|
|
3
4
|
|
|
@@ -61,33 +62,44 @@ class Renderer:
|
|
|
61
62
|
else:
|
|
62
63
|
raise ValueError(f'Unknown link type: {link.type}')
|
|
63
64
|
|
|
64
|
-
def
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
65
|
+
def render_module_schema_wrapper(self, mods: list[ModuleNode]) -> str:
|
|
66
|
+
module_color_flag = set(self.module_color.keys())
|
|
67
|
+
print(module_color_flag)
|
|
68
|
+
|
|
69
|
+
def render_module_schema(mod: ModuleNode) -> str:
|
|
70
|
+
color: Optional[str] = None
|
|
71
|
+
|
|
72
|
+
for k in module_color_flag:
|
|
73
|
+
if mod.fullname.startswith(k):
|
|
74
|
+
module_color_flag.remove(k)
|
|
75
|
+
color = self.module_color[k]
|
|
76
|
+
break
|
|
77
|
+
|
|
78
|
+
inner_nodes = [
|
|
79
|
+
f'''
|
|
80
|
+
"{node.id}" [
|
|
81
|
+
label = {self.render_schema_label(node)}
|
|
82
|
+
shape = "plain"
|
|
83
|
+
margin="0.5,0.1"
|
|
84
|
+
];''' for node in mod.schema_nodes
|
|
85
|
+
]
|
|
86
|
+
inner_nodes_str = '\n'.join(inner_nodes)
|
|
87
|
+
child_str = '\n'.join(render_module_schema(m) for m in mod.modules)
|
|
88
|
+
return f'''
|
|
89
|
+
subgraph cluster_module_{mod.fullname.replace('.', '_')} {{
|
|
90
|
+
tooltip="{mod.fullname}"
|
|
91
|
+
color = "#666"
|
|
92
|
+
style="rounded"
|
|
93
|
+
label = " {mod.name}"
|
|
94
|
+
labeljust = "l"
|
|
95
|
+
{(f'pencolor = "{color}"' if color else 'pencolor="#ccc"')}
|
|
96
|
+
{(f'penwidth = 3' if color else 'penwidth=""')}
|
|
97
|
+
{inner_nodes_str}
|
|
98
|
+
{child_str}
|
|
99
|
+
}}'''
|
|
100
|
+
return '\n'.join(render_module_schema(m) for m in mods)
|
|
88
101
|
|
|
89
102
|
def render_module_route(self, mod: ModuleRoute) -> str:
|
|
90
|
-
color = self.module_color.get(mod.fullname)
|
|
91
103
|
# Inner route nodes, same style as flat route_str
|
|
92
104
|
inner_nodes = [
|
|
93
105
|
f'''
|
|
@@ -106,8 +118,6 @@ class Renderer:
|
|
|
106
118
|
style="rounded"
|
|
107
119
|
label = " {mod.name}"
|
|
108
120
|
labeljust = "l"
|
|
109
|
-
{(f'pencolor = "{color}"' if color else 'pencolor="#ccc"')}
|
|
110
|
-
{(f'penwidth = 3' if color else 'penwidth=""')}
|
|
111
121
|
{inner_nodes_str}
|
|
112
122
|
{child_str}
|
|
113
123
|
}}'''
|
|
@@ -126,7 +136,7 @@ class Renderer:
|
|
|
126
136
|
])
|
|
127
137
|
|
|
128
138
|
|
|
129
|
-
module_schemas_str =
|
|
139
|
+
module_schemas_str = self.render_module_schema_wrapper(module_schemas)
|
|
130
140
|
module_routes_str = '\n'.join(self.render_module_route(m) for m in module_routes)
|
|
131
141
|
link_str = '\n'.join(self.render_link(link) for link in links)
|
|
132
142
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "0.7.
|
|
2
|
+
__version__ = "0.7.4"
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>FastAPI Voyager</title>
|
|
4
|
+
<meta name="theme-color" content="#ffffff" />
|
|
5
|
+
<link rel="stylesheet" href="fastapi-voyager-static/graphviz.svg.css" />
|
|
6
|
+
<link rel="stylesheet" href="fastapi-voyager-static/quasar.min.css" />
|
|
7
|
+
<!-- App Icons / Favicons -->
|
|
8
|
+
<link
|
|
9
|
+
rel="apple-touch-icon"
|
|
10
|
+
sizes="180x180"
|
|
11
|
+
href="fastapi-voyager-static/icon/apple-touch-icon.png"
|
|
12
|
+
/>
|
|
13
|
+
<link
|
|
14
|
+
rel="icon"
|
|
15
|
+
type="image/png"
|
|
16
|
+
sizes="32x32"
|
|
17
|
+
href="fastapi-voyager-static/icon/favicon-32x32.png"
|
|
18
|
+
/>
|
|
19
|
+
<link
|
|
20
|
+
rel="icon"
|
|
21
|
+
type="image/png"
|
|
22
|
+
sizes="16x16"
|
|
23
|
+
href="fastapi-voyager-static/icon/favicon-16x16.png"
|
|
24
|
+
/>
|
|
25
|
+
<link
|
|
26
|
+
rel="icon"
|
|
27
|
+
href="fastapi-voyager-static/icon/favicon.ico"
|
|
28
|
+
sizes="any"
|
|
29
|
+
/>
|
|
30
|
+
<link rel="manifest" href="fastapi-voyager-static/icon/site.webmanifest" />
|
|
31
|
+
<link
|
|
32
|
+
href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
|
|
33
|
+
rel="stylesheet"
|
|
34
|
+
type="text/css"
|
|
35
|
+
/>
|
|
36
|
+
</head>
|
|
37
|
+
|
|
38
|
+
<style>
|
|
39
|
+
html,
|
|
40
|
+
body {
|
|
41
|
+
height: 100%;
|
|
42
|
+
margin: 0;
|
|
43
|
+
}
|
|
44
|
+
body {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
}
|
|
48
|
+
/* Quasar select menu max-height for scroll */
|
|
49
|
+
.select-popup {
|
|
50
|
+
max-height: 400px;
|
|
51
|
+
overflow-y: auto;
|
|
52
|
+
overflow-x: hidden;
|
|
53
|
+
}
|
|
54
|
+
#graph {
|
|
55
|
+
flex: 1 1 auto;
|
|
56
|
+
overflow: auto;
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
59
|
+
<body>
|
|
60
|
+
<div id="q-app" class="column" style="height: 100%">
|
|
61
|
+
<div
|
|
62
|
+
v-if="state.initializing"
|
|
63
|
+
style="
|
|
64
|
+
position: fixed;
|
|
65
|
+
inset: 0;
|
|
66
|
+
display: flex;
|
|
67
|
+
align-items: center;
|
|
68
|
+
justify-content: center;
|
|
69
|
+
z-index: 2000;
|
|
70
|
+
background: rgba(255, 255, 255, 0.85);
|
|
71
|
+
font-size: 18px;
|
|
72
|
+
font-family: Roboto, sans-serif;
|
|
73
|
+
color: #444;
|
|
74
|
+
"
|
|
75
|
+
>
|
|
76
|
+
<div style="text-align: center">
|
|
77
|
+
<div class="q-mb-sm">Initializing...</div>
|
|
78
|
+
<q-spinner color="primary" size="32px" />
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
<div
|
|
82
|
+
style="
|
|
83
|
+
padding: 8px;
|
|
84
|
+
background-color: #fff;
|
|
85
|
+
border-bottom: 1px solid #ccc;
|
|
86
|
+
color: #211d1d;
|
|
87
|
+
flex: 0 0 auto;
|
|
88
|
+
"
|
|
89
|
+
>
|
|
90
|
+
<div class="row items-center q-col-gutter-md">
|
|
91
|
+
<div class="col-auto">
|
|
92
|
+
<div class="column">
|
|
93
|
+
<q-option-group
|
|
94
|
+
v-model="state.showFields"
|
|
95
|
+
:options="state.fieldOptions"
|
|
96
|
+
color="primary"
|
|
97
|
+
type="radio"
|
|
98
|
+
inline
|
|
99
|
+
dense
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div class="col-auto">
|
|
105
|
+
<q-toggle v-model="state.brief" label="Brief" dense />
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<!-- <div class="col-auto">
|
|
109
|
+
<q-btn-dropdown
|
|
110
|
+
class="q-ml-md"
|
|
111
|
+
split
|
|
112
|
+
:loading="state.generating"
|
|
113
|
+
@click="onGenerate"
|
|
114
|
+
label="Generate"
|
|
115
|
+
outline
|
|
116
|
+
>
|
|
117
|
+
<q-list>
|
|
118
|
+
<q-item clickable v-close-popup @click="onDumpData">
|
|
119
|
+
<q-item-section>Dump data</q-item-section>
|
|
120
|
+
</q-item>
|
|
121
|
+
<q-item clickable v-close-popup @click="openImportDialog">
|
|
122
|
+
<q-item-section>Import data</q-item-section>
|
|
123
|
+
</q-item>
|
|
124
|
+
</q-list>
|
|
125
|
+
</q-btn-dropdown>
|
|
126
|
+
</div> -->
|
|
127
|
+
|
|
128
|
+
<div class="col-auto q-ml-auto">
|
|
129
|
+
<q-btn outline @click="onReset" title="may be very slow" label="Show All" />
|
|
130
|
+
</div>
|
|
131
|
+
<div class="col-auto">
|
|
132
|
+
<q-btn outline icon="search" label="Search" @click="showDialog()" />
|
|
133
|
+
</div>
|
|
134
|
+
<div class="col-auto">
|
|
135
|
+
<q-btn
|
|
136
|
+
dense
|
|
137
|
+
round
|
|
138
|
+
flat
|
|
139
|
+
icon="help_outline"
|
|
140
|
+
aria-label="Help"
|
|
141
|
+
class="q-mr-md"
|
|
142
|
+
>
|
|
143
|
+
<q-tooltip
|
|
144
|
+
anchor="bottom middle"
|
|
145
|
+
self="top middle"
|
|
146
|
+
:offset="[0,8]"
|
|
147
|
+
>
|
|
148
|
+
<div
|
|
149
|
+
class="column items-start text-left"
|
|
150
|
+
style="line-height: 1.4; font-size: 12px"
|
|
151
|
+
>
|
|
152
|
+
<ul>
|
|
153
|
+
<li>scroll to zoom in/out</li>
|
|
154
|
+
<li>
|
|
155
|
+
click node to check highlight related nodes on the chart,
|
|
156
|
+
esc to unselect
|
|
157
|
+
</li>
|
|
158
|
+
<li>
|
|
159
|
+
shift + click to see schema's dependencies without
|
|
160
|
+
unrelated nodes
|
|
161
|
+
</li>
|
|
162
|
+
<li>alt + click to see schema details</li>
|
|
163
|
+
</ul>
|
|
164
|
+
</div>
|
|
165
|
+
</q-tooltip>
|
|
166
|
+
</q-btn>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="row no-wrap" style="flex: 1 1 auto; min-height: 0">
|
|
171
|
+
<div
|
|
172
|
+
class="column no-wrap"
|
|
173
|
+
:style="{
|
|
174
|
+
minWidth: '300px',
|
|
175
|
+
width: '300px',
|
|
176
|
+
borderRight: '1px solid #e0e0e0',
|
|
177
|
+
backgroundColor: '#fff',
|
|
178
|
+
minHeight: 0,
|
|
179
|
+
}"
|
|
180
|
+
>
|
|
181
|
+
<q-scroll-area class="fit">
|
|
182
|
+
<q-list dense separator>
|
|
183
|
+
<q-expansion-item
|
|
184
|
+
v-for="tag in state.rawTags"
|
|
185
|
+
:key="tag.name"
|
|
186
|
+
expand-separator
|
|
187
|
+
switch-toggle-side
|
|
188
|
+
:model-value="state.tag === tag.name"
|
|
189
|
+
@update:model-value="(val) => toggleTag(tag.name, val)"
|
|
190
|
+
:header-class="state.tag === tag.name ? 'bg-primary text-white text-weight-medium' : 'text-weight-medium'"
|
|
191
|
+
content-class="q-pa-none"
|
|
192
|
+
>
|
|
193
|
+
<template #header>
|
|
194
|
+
<div class="row items-center no-wrap" style="width: 100%">
|
|
195
|
+
<div class="col text-body2">{{ tag.name }}</div>
|
|
196
|
+
</div>
|
|
197
|
+
</template>
|
|
198
|
+
|
|
199
|
+
<q-list separator>
|
|
200
|
+
<q-item
|
|
201
|
+
v-for="route in (tag.routes || [])"
|
|
202
|
+
:key="route.id"
|
|
203
|
+
clickable
|
|
204
|
+
v-ripple
|
|
205
|
+
:active="state.routeId === route.id"
|
|
206
|
+
active-class=""
|
|
207
|
+
@click="selectRoute(route.id)"
|
|
208
|
+
>
|
|
209
|
+
<q-item-section>{{ route.name }}</q-item-section>
|
|
210
|
+
</q-item>
|
|
211
|
+
<q-item v-if="!tag.routes || tag.routes.length === 0" dense>
|
|
212
|
+
<q-item-section class="text-grey-6">No routes</q-item-section>
|
|
213
|
+
</q-item>
|
|
214
|
+
</q-list>
|
|
215
|
+
</q-expansion-item>
|
|
216
|
+
</q-list>
|
|
217
|
+
</q-scroll-area>
|
|
218
|
+
</div>
|
|
219
|
+
<div id="graph"></div>
|
|
220
|
+
</div>
|
|
221
|
+
|
|
222
|
+
<!-- Detail Dialog -->
|
|
223
|
+
<q-dialog v-model="showDetail" :persistent="true" :maximized="true">
|
|
224
|
+
<detail-dialog
|
|
225
|
+
:schema-name="schemaName"
|
|
226
|
+
:show-fields="state.showFields"
|
|
227
|
+
:model-value="showDetail"
|
|
228
|
+
@close="closeDetail"
|
|
229
|
+
/>
|
|
230
|
+
</q-dialog>
|
|
231
|
+
|
|
232
|
+
<!-- Schema Field Filter Dialog -->
|
|
233
|
+
<q-dialog
|
|
234
|
+
v-model="showSchemaFieldFilter"
|
|
235
|
+
:persistent="true"
|
|
236
|
+
:maximized="true"
|
|
237
|
+
>
|
|
238
|
+
<schema-field-filter
|
|
239
|
+
:schemas="state.rawSchemasFull"
|
|
240
|
+
:schema-name="schemaFieldFilterSchema"
|
|
241
|
+
@close="showSchemaFieldFilter = false"
|
|
242
|
+
/>
|
|
243
|
+
</q-dialog>
|
|
244
|
+
|
|
245
|
+
<!-- Schema Source Code Dialog (Ctrl + Click) -->
|
|
246
|
+
<q-dialog
|
|
247
|
+
v-model="showSchemaCode"
|
|
248
|
+
:maximized="true"
|
|
249
|
+
:persistent="false"
|
|
250
|
+
position="left"
|
|
251
|
+
:seamless="false"
|
|
252
|
+
>
|
|
253
|
+
<schema-code-display
|
|
254
|
+
:schema-name="schemaCodeName"
|
|
255
|
+
:model-value="showSchemaCode"
|
|
256
|
+
:schemas="state.rawSchemasFull"
|
|
257
|
+
@close="showSchemaCode = false"
|
|
258
|
+
/>
|
|
259
|
+
</q-dialog>
|
|
260
|
+
|
|
261
|
+
<!-- Route Source Code Dialog (Alt + Click on route) -->
|
|
262
|
+
<q-dialog
|
|
263
|
+
v-model="showRouteCode"
|
|
264
|
+
:maximized="true"
|
|
265
|
+
:persistent="false"
|
|
266
|
+
position="right"
|
|
267
|
+
:seamless="false"
|
|
268
|
+
>
|
|
269
|
+
<route-code-display
|
|
270
|
+
:route-id="routeCodeId"
|
|
271
|
+
:model-value="showRouteCode"
|
|
272
|
+
:routes="state.routeItems"
|
|
273
|
+
@close="showRouteCode = false"
|
|
274
|
+
/>
|
|
275
|
+
</q-dialog>
|
|
276
|
+
|
|
277
|
+
<!-- Dump Core Data Dialog -->
|
|
278
|
+
<q-dialog v-model="showDumpDialog" :maximized="true" :persistent="false">
|
|
279
|
+
<div style="height: 100%; position: relative; background: #fff">
|
|
280
|
+
<q-btn
|
|
281
|
+
flat
|
|
282
|
+
dense
|
|
283
|
+
round
|
|
284
|
+
icon="content_copy"
|
|
285
|
+
aria-label="Copy"
|
|
286
|
+
@click="copyDumpJson"
|
|
287
|
+
style="
|
|
288
|
+
position: absolute;
|
|
289
|
+
top: 6px;
|
|
290
|
+
right: 62px;
|
|
291
|
+
z-index: 11;
|
|
292
|
+
background: rgba(255, 255, 255, 0.85);
|
|
293
|
+
"
|
|
294
|
+
></q-btn>
|
|
295
|
+
<q-btn
|
|
296
|
+
flat
|
|
297
|
+
dense
|
|
298
|
+
round
|
|
299
|
+
icon="close"
|
|
300
|
+
aria-label="Close"
|
|
301
|
+
@click="showDumpDialog = false"
|
|
302
|
+
style="
|
|
303
|
+
position: absolute;
|
|
304
|
+
top: 6px;
|
|
305
|
+
right: 6px;
|
|
306
|
+
z-index: 11;
|
|
307
|
+
background: rgba(255, 255, 255, 0.85);
|
|
308
|
+
"
|
|
309
|
+
></q-btn>
|
|
310
|
+
<div>
|
|
311
|
+
<pre
|
|
312
|
+
style="padding: 20px; overflow: auto"
|
|
313
|
+
><code>{{ dumpJson }}</code></pre>
|
|
314
|
+
</div>
|
|
315
|
+
</div>
|
|
316
|
+
</q-dialog>
|
|
317
|
+
|
|
318
|
+
<!-- Import Core Data Dialog -->
|
|
319
|
+
<q-dialog v-model="showImportDialog" :persistent="true">
|
|
320
|
+
<q-card style="min-width: 70vw; max-width: 90vw">
|
|
321
|
+
<q-card-section class="text-h6">Import core data JSON</q-card-section>
|
|
322
|
+
<q-card-section>
|
|
323
|
+
<q-btn color="primary" label="Render" @click="onImportConfirm" />
|
|
324
|
+
</q-card-section>
|
|
325
|
+
<q-card-section>
|
|
326
|
+
<q-input
|
|
327
|
+
v-model="importJsonText"
|
|
328
|
+
type="textarea"
|
|
329
|
+
autogrow
|
|
330
|
+
filled
|
|
331
|
+
label="Paste JSON here"
|
|
332
|
+
/>
|
|
333
|
+
</q-card-section>
|
|
334
|
+
</q-card>
|
|
335
|
+
</q-dialog>
|
|
336
|
+
|
|
337
|
+
<!-- Render Graph Dialog (from imported core data) -->
|
|
338
|
+
<q-dialog v-model="showRenderGraph" :maximized="true" :persistent="false">
|
|
339
|
+
<render-graph
|
|
340
|
+
:core-data="renderCoreData"
|
|
341
|
+
@close="showRenderGraph = false"
|
|
342
|
+
/>
|
|
343
|
+
</q-dialog>
|
|
344
|
+
</div>
|
|
345
|
+
|
|
346
|
+
<script
|
|
347
|
+
type="text/javascript"
|
|
348
|
+
src="https://code.jquery.com/jquery-2.1.3.min.js"
|
|
349
|
+
></script>
|
|
350
|
+
<script
|
|
351
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"
|
|
352
|
+
integrity="sha512-vc58qvvBdrDR4etbxMdlTt4GBQk1qjvyORR2nrsPsFPyrs+/u5c3+1Ct6upOgdZoIl7eq6k3a1UPDSNAQi/32A=="
|
|
353
|
+
crossorigin="anonymous"
|
|
354
|
+
referrerpolicy="no-referrer"
|
|
355
|
+
></script>
|
|
356
|
+
<script src="https://unpkg.com/@hpcc-js/wasm@2.20.0/dist/graphviz.umd.js"></script>
|
|
357
|
+
<script src="https://unpkg.com/d3-graphviz@5.6.0/build/d3-graphviz.js"></script>
|
|
358
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"></script>
|
|
359
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.min.js"></script>
|
|
360
|
+
|
|
361
|
+
<!-- Add the following at the end of your body tag -->
|
|
362
|
+
<script
|
|
363
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.5.22/vue.global.prod.min.js"
|
|
364
|
+
integrity="sha512-Y9sKU0AwzWRxKSLd2i35LuDpUdHY/E9tJrKG0mxw0qYQ75VVgGYazIUQPwKhFK9vGO3jIgAtxLiSq8GQ7PDfUg=="
|
|
365
|
+
crossorigin="anonymous"
|
|
366
|
+
referrerpolicy="no-referrer"
|
|
367
|
+
></script>
|
|
368
|
+
<script src="fastapi-voyager-static/quasar.min.js"></script>
|
|
369
|
+
<script src="fastapi-voyager-static/graphviz.svg.js"></script>
|
|
370
|
+
<!-- highlight.js minimal ES module load (python only) -->
|
|
371
|
+
<link
|
|
372
|
+
rel="stylesheet"
|
|
373
|
+
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css"
|
|
374
|
+
/>
|
|
375
|
+
<script type="module">
|
|
376
|
+
import hljs from "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/highlight.min.js";
|
|
377
|
+
import python from "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/languages/python.min.js";
|
|
378
|
+
hljs.registerLanguage("python", python);
|
|
379
|
+
window.hljs = hljs;
|
|
380
|
+
</script>
|
|
381
|
+
<script type="module" src="fastapi-voyager-static/vue-main.js"></script>
|
|
382
|
+
</body>
|
|
383
|
+
</html>
|
|
@@ -51,6 +51,8 @@ const app = createApp({
|
|
|
51
51
|
showDetail.value = false;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
const skipNextRouteGenerate = ref(false);
|
|
55
|
+
|
|
54
56
|
function applyRoutesForTag(tagName) {
|
|
55
57
|
const tag = state.rawTags.find((t) => t.name === tagName);
|
|
56
58
|
state.routeOptions = [];
|
|
@@ -59,6 +61,7 @@ const app = createApp({
|
|
|
59
61
|
...tag.routes.map((r) => ({ label: r.name, value: r.id }))
|
|
60
62
|
);
|
|
61
63
|
}
|
|
64
|
+
skipNextRouteGenerate.value = true;
|
|
62
65
|
state.routeId = "";
|
|
63
66
|
}
|
|
64
67
|
|
|
@@ -242,7 +245,19 @@ const app = createApp({
|
|
|
242
245
|
state.schemaFullname = null;
|
|
243
246
|
state.showFields = "object";
|
|
244
247
|
state.brief = false;
|
|
245
|
-
|
|
248
|
+
onGenerate()
|
|
249
|
+
// await loadInitial();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function toggleTag(tagName, expanded = null) {
|
|
253
|
+
if (expanded === true) {
|
|
254
|
+
state.tag = tagName;
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function selectRoute(routeId) {
|
|
260
|
+
state.routeId = state.routeId === routeId ? "" : routeId;
|
|
246
261
|
}
|
|
247
262
|
|
|
248
263
|
// react to tag changes to rebuild routes
|
|
@@ -250,6 +265,40 @@ const app = createApp({
|
|
|
250
265
|
() => state.tag,
|
|
251
266
|
(val) => {
|
|
252
267
|
applyRoutesForTag(val);
|
|
268
|
+
if (!state.initializing) {
|
|
269
|
+
onGenerate();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
watch(
|
|
275
|
+
() => state.routeId,
|
|
276
|
+
() => {
|
|
277
|
+
if (skipNextRouteGenerate.value) {
|
|
278
|
+
skipNextRouteGenerate.value = false;
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (!state.initializing) {
|
|
282
|
+
onGenerate();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
watch(
|
|
288
|
+
() => state.showFields,
|
|
289
|
+
() => {
|
|
290
|
+
if (!state.initializing) {
|
|
291
|
+
onGenerate();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
watch(
|
|
297
|
+
() => state.brief,
|
|
298
|
+
() => {
|
|
299
|
+
if (!state.initializing) {
|
|
300
|
+
onGenerate();
|
|
301
|
+
}
|
|
253
302
|
}
|
|
254
303
|
);
|
|
255
304
|
|
|
@@ -259,6 +308,8 @@ const app = createApp({
|
|
|
259
308
|
|
|
260
309
|
return {
|
|
261
310
|
state,
|
|
311
|
+
toggleTag,
|
|
312
|
+
selectRoute,
|
|
262
313
|
onFilterTags,
|
|
263
314
|
onFilterSchemas,
|
|
264
315
|
onGenerate,
|
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
<html>
|
|
2
|
-
<head>
|
|
3
|
-
<title>FastAPI Voyager</title>
|
|
4
|
-
<meta name="theme-color" content="#ffffff" />
|
|
5
|
-
<link rel="stylesheet" href="fastapi-voyager-static/graphviz.svg.css" />
|
|
6
|
-
<link rel="stylesheet" href="fastapi-voyager-static/quasar.min.css" />
|
|
7
|
-
<!-- App Icons / Favicons -->
|
|
8
|
-
<link rel="apple-touch-icon" sizes="180x180" href="fastapi-voyager-static/icon/apple-touch-icon.png" />
|
|
9
|
-
<link rel="icon" type="image/png" sizes="32x32" href="fastapi-voyager-static/icon/favicon-32x32.png" />
|
|
10
|
-
<link rel="icon" type="image/png" sizes="16x16" href="fastapi-voyager-static/icon/favicon-16x16.png" />
|
|
11
|
-
<link rel="icon" href="fastapi-voyager-static/icon/favicon.ico" sizes="any" />
|
|
12
|
-
<link rel="manifest" href="fastapi-voyager-static/icon/site.webmanifest" />
|
|
13
|
-
<link
|
|
14
|
-
href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
|
|
15
|
-
rel="stylesheet"
|
|
16
|
-
type="text/css"
|
|
17
|
-
/>
|
|
18
|
-
</head>
|
|
19
|
-
|
|
20
|
-
<style>
|
|
21
|
-
html,
|
|
22
|
-
body {
|
|
23
|
-
height: 100%;
|
|
24
|
-
margin: 0;
|
|
25
|
-
}
|
|
26
|
-
body {
|
|
27
|
-
display: flex;
|
|
28
|
-
flex-direction: column;
|
|
29
|
-
}
|
|
30
|
-
/* Quasar select menu max-height for scroll */
|
|
31
|
-
.select-popup {
|
|
32
|
-
max-height: 400px;
|
|
33
|
-
overflow-y: auto;
|
|
34
|
-
overflow-x: hidden;
|
|
35
|
-
}
|
|
36
|
-
#graph {
|
|
37
|
-
flex: 1 1 auto;
|
|
38
|
-
overflow: auto;
|
|
39
|
-
}
|
|
40
|
-
</style>
|
|
41
|
-
<body>
|
|
42
|
-
<div id="q-app" class="column" style="height: 100%">
|
|
43
|
-
<div v-if="state.initializing" style="position:fixed; inset:0; display:flex; align-items:center; justify-content:center; z-index:2000; background:rgba(255,255,255,0.85); font-size:18px; font-family:Roboto, sans-serif; color:#444;">
|
|
44
|
-
<div style="text-align:center;">
|
|
45
|
-
<div class="q-mb-sm">Initializing...</div>
|
|
46
|
-
<q-spinner color="primary" size="32px" />
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
<div
|
|
50
|
-
style="
|
|
51
|
-
padding-top: 8px;
|
|
52
|
-
padding-left: 8px;
|
|
53
|
-
padding-bottom: 8px;
|
|
54
|
-
position: absolute;
|
|
55
|
-
width: 100%;
|
|
56
|
-
top: 0;
|
|
57
|
-
background-color: #fff;
|
|
58
|
-
z-index: 1;
|
|
59
|
-
border-bottom: 1px solid #ccc;
|
|
60
|
-
color: #211d1d;
|
|
61
|
-
"
|
|
62
|
-
>
|
|
63
|
-
<div class="row items-center q-col-gutter-md">
|
|
64
|
-
<div class="col-auto">
|
|
65
|
-
<q-select
|
|
66
|
-
v-model="state.tag"
|
|
67
|
-
:options="state.tagOptions"
|
|
68
|
-
use-input
|
|
69
|
-
input-debounce="0"
|
|
70
|
-
behavior="menu"
|
|
71
|
-
dense
|
|
72
|
-
outlined
|
|
73
|
-
style="min-width: 320px"
|
|
74
|
-
popup-content-class="select-popup"
|
|
75
|
-
clearable
|
|
76
|
-
label="Tags"
|
|
77
|
-
@filter="onFilterTags"
|
|
78
|
-
/>
|
|
79
|
-
</div>
|
|
80
|
-
|
|
81
|
-
<div class="col-auto">
|
|
82
|
-
<q-select
|
|
83
|
-
v-model="state.routeId"
|
|
84
|
-
:options="state.routeOptions"
|
|
85
|
-
option-label="label"
|
|
86
|
-
option-value="value"
|
|
87
|
-
emit-value
|
|
88
|
-
map-options
|
|
89
|
-
dense
|
|
90
|
-
outlined
|
|
91
|
-
style="min-width: 320px"
|
|
92
|
-
popup-content-class="select-popup"
|
|
93
|
-
clearable
|
|
94
|
-
placeholder="All routes"
|
|
95
|
-
label="Routes"
|
|
96
|
-
/>
|
|
97
|
-
</div>
|
|
98
|
-
|
|
99
|
-
<div class="col-auto">
|
|
100
|
-
<div class="column">
|
|
101
|
-
<q-option-group
|
|
102
|
-
v-model="state.showFields"
|
|
103
|
-
:options="state.fieldOptions"
|
|
104
|
-
color="primary"
|
|
105
|
-
type="radio"
|
|
106
|
-
inline
|
|
107
|
-
dense
|
|
108
|
-
/>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
<div class="col-auto">
|
|
113
|
-
<q-checkbox
|
|
114
|
-
v-model="state.brief"
|
|
115
|
-
label="Brief"
|
|
116
|
-
dense
|
|
117
|
-
/>
|
|
118
|
-
</div>
|
|
119
|
-
|
|
120
|
-
<div class="col-auto">
|
|
121
|
-
<q-btn-dropdown
|
|
122
|
-
class="q-ml-md"
|
|
123
|
-
split
|
|
124
|
-
:loading="state.generating"
|
|
125
|
-
@click="onGenerate"
|
|
126
|
-
label="Generate"
|
|
127
|
-
outline
|
|
128
|
-
>
|
|
129
|
-
<q-list>
|
|
130
|
-
<q-item clickable v-close-popup @click="onDumpData">
|
|
131
|
-
<q-item-section>Dump data</q-item-section>
|
|
132
|
-
</q-item>
|
|
133
|
-
<q-item clickable v-close-popup @click="openImportDialog">
|
|
134
|
-
<q-item-section>Import data</q-item-section>
|
|
135
|
-
</q-item>
|
|
136
|
-
</q-list>
|
|
137
|
-
</q-btn-dropdown>
|
|
138
|
-
</div>
|
|
139
|
-
<div class="col-auto">
|
|
140
|
-
<q-btn flat @click="onReset" label="Reset" />
|
|
141
|
-
</div>
|
|
142
|
-
<div class="col-auto q-ml-auto">
|
|
143
|
-
<q-btn
|
|
144
|
-
outline
|
|
145
|
-
icon="search"
|
|
146
|
-
label="Search"
|
|
147
|
-
@click="showDialog()"
|
|
148
|
-
/>
|
|
149
|
-
</div>
|
|
150
|
-
<div class="col-auto">
|
|
151
|
-
<q-btn
|
|
152
|
-
dense
|
|
153
|
-
round
|
|
154
|
-
flat
|
|
155
|
-
icon="help_outline"
|
|
156
|
-
aria-label="Help"
|
|
157
|
-
class="q-mr-md"
|
|
158
|
-
>
|
|
159
|
-
<q-tooltip
|
|
160
|
-
anchor="bottom middle"
|
|
161
|
-
self="top middle"
|
|
162
|
-
:offset="[0,8]"
|
|
163
|
-
>
|
|
164
|
-
<div
|
|
165
|
-
class="column items-start text-left"
|
|
166
|
-
style="line-height: 1.4; font-size: 12px"
|
|
167
|
-
>
|
|
168
|
-
<ul>
|
|
169
|
-
<li>scroll to zoom in/out</li>
|
|
170
|
-
<li>
|
|
171
|
-
click node to check highlight related nodes on the chart,
|
|
172
|
-
esc to unselect
|
|
173
|
-
</li>
|
|
174
|
-
<li>
|
|
175
|
-
shift + click to see schema's dependencies without
|
|
176
|
-
unrelated nodes
|
|
177
|
-
</li>
|
|
178
|
-
<li>alt + click to see schema details</li>
|
|
179
|
-
</ul>
|
|
180
|
-
</div>
|
|
181
|
-
</q-tooltip>
|
|
182
|
-
</q-btn>
|
|
183
|
-
</div>
|
|
184
|
-
</div>
|
|
185
|
-
</div>
|
|
186
|
-
<!-- Detail Dialog -->
|
|
187
|
-
<q-dialog v-model="showDetail" :persistent="true" :maximized="true">
|
|
188
|
-
<detail-dialog
|
|
189
|
-
:schema-name="schemaName"
|
|
190
|
-
:show-fields="state.showFields"
|
|
191
|
-
:model-value="showDetail"
|
|
192
|
-
@close="closeDetail"
|
|
193
|
-
/>
|
|
194
|
-
</q-dialog>
|
|
195
|
-
|
|
196
|
-
<!-- Schema Field Filter Dialog -->
|
|
197
|
-
<q-dialog
|
|
198
|
-
v-model="showSchemaFieldFilter"
|
|
199
|
-
:persistent="true"
|
|
200
|
-
:maximized="true"
|
|
201
|
-
>
|
|
202
|
-
<schema-field-filter
|
|
203
|
-
:schemas="state.rawSchemasFull"
|
|
204
|
-
:schema-name="schemaFieldFilterSchema" @close="showSchemaFieldFilter = false" />
|
|
205
|
-
</q-dialog>
|
|
206
|
-
|
|
207
|
-
<!-- Schema Source Code Dialog (Ctrl + Click) -->
|
|
208
|
-
<q-dialog v-model="showSchemaCode" :maximized="true" :persistent="false" position="left" :seamless="false">
|
|
209
|
-
<schema-code-display
|
|
210
|
-
:schema-name="schemaCodeName"
|
|
211
|
-
:model-value="showSchemaCode"
|
|
212
|
-
:schemas="state.rawSchemasFull"
|
|
213
|
-
@close="showSchemaCode = false" />
|
|
214
|
-
</q-dialog>
|
|
215
|
-
|
|
216
|
-
<!-- Route Source Code Dialog (Alt + Click on route) -->
|
|
217
|
-
<q-dialog v-model="showRouteCode" :maximized="true" :persistent="false" position="right" :seamless="false">
|
|
218
|
-
<route-code-display
|
|
219
|
-
:route-id="routeCodeId"
|
|
220
|
-
:model-value="showRouteCode"
|
|
221
|
-
:routes="state.routeItems"
|
|
222
|
-
@close="showRouteCode = false" />
|
|
223
|
-
</q-dialog>
|
|
224
|
-
|
|
225
|
-
<!-- Dump Core Data Dialog -->
|
|
226
|
-
<q-dialog v-model="showDumpDialog" :maximized="true" :persistent="false">
|
|
227
|
-
<div style="height:100%; position:relative; background:#fff;">
|
|
228
|
-
<q-btn
|
|
229
|
-
flat dense round icon="content_copy"
|
|
230
|
-
aria-label="Copy"
|
|
231
|
-
@click="copyDumpJson"
|
|
232
|
-
style="position:absolute; top:6px; right:62px; z-index:11; background:rgba(255,255,255,0.85);"
|
|
233
|
-
></q-btn>
|
|
234
|
-
<q-btn
|
|
235
|
-
flat dense round icon="close"
|
|
236
|
-
aria-label="Close"
|
|
237
|
-
@click="showDumpDialog = false"
|
|
238
|
-
style="position:absolute; top:6px; right:6px; z-index:11; background:rgba(255,255,255,0.85);"
|
|
239
|
-
></q-btn>
|
|
240
|
-
<div>
|
|
241
|
-
<pre style="padding:20px; overflow: auto;"><code>{{ dumpJson }}</code></pre>
|
|
242
|
-
</div>
|
|
243
|
-
</div>
|
|
244
|
-
</q-dialog>
|
|
245
|
-
|
|
246
|
-
<!-- Import Core Data Dialog -->
|
|
247
|
-
<q-dialog v-model="showImportDialog" :persistent="true">
|
|
248
|
-
<q-card style="min-width:70vw; max-width:90vw;">
|
|
249
|
-
<q-card-section class="text-h6">Import core data JSON</q-card-section>
|
|
250
|
-
<q-card-section >
|
|
251
|
-
<q-btn color="primary" label="Render" @click="onImportConfirm" />
|
|
252
|
-
</q-card-section>
|
|
253
|
-
<q-card-section>
|
|
254
|
-
<q-input v-model="importJsonText" type="textarea" autogrow filled label="Paste JSON here" />
|
|
255
|
-
</q-card-section>
|
|
256
|
-
</q-card>
|
|
257
|
-
</q-dialog>
|
|
258
|
-
|
|
259
|
-
<!-- Render Graph Dialog (from imported core data) -->
|
|
260
|
-
<q-dialog v-model="showRenderGraph" :maximized="true" :persistent="false">
|
|
261
|
-
<render-graph :core-data="renderCoreData" @close="showRenderGraph = false" />
|
|
262
|
-
</q-dialog>
|
|
263
|
-
|
|
264
|
-
<div id="graph" style="width: 100%; flex: 1 1 auto; overflow: auto"></div>
|
|
265
|
-
</div>
|
|
266
|
-
|
|
267
|
-
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js" ></script>
|
|
268
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js" integrity="sha512-vc58qvvBdrDR4etbxMdlTt4GBQk1qjvyORR2nrsPsFPyrs+/u5c3+1Ct6upOgdZoIl7eq6k3a1UPDSNAQi/32A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
269
|
-
<script src="https://unpkg.com/@hpcc-js/wasm@2.20.0/dist/graphviz.umd.js"></script>
|
|
270
|
-
<script src="https://unpkg.com/d3-graphviz@5.6.0/build/d3-graphviz.js"></script>
|
|
271
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"></script>
|
|
272
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.min.js"></script>
|
|
273
|
-
|
|
274
|
-
<!-- Add the following at the end of your body tag -->
|
|
275
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.5.22/vue.global.prod.min.js" integrity="sha512-Y9sKU0AwzWRxKSLd2i35LuDpUdHY/E9tJrKG0mxw0qYQ75VVgGYazIUQPwKhFK9vGO3jIgAtxLiSq8GQ7PDfUg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
276
|
-
<script src="fastapi-voyager-static/quasar.min.js"></script>
|
|
277
|
-
<script src="fastapi-voyager-static/graphviz.svg.js"></script>
|
|
278
|
-
<!-- highlight.js minimal ES module load (python only) -->
|
|
279
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css" />
|
|
280
|
-
<script type="module">
|
|
281
|
-
import hljs from 'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/highlight.min.js';
|
|
282
|
-
import python from 'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/es/languages/python.min.js';
|
|
283
|
-
hljs.registerLanguage('python', python);
|
|
284
|
-
window.hljs = hljs;
|
|
285
|
-
</script>
|
|
286
|
-
<script type="module" src="fastapi-voyager-static/vue-main.js"></script>
|
|
287
|
-
</body>
|
|
288
|
-
</html>
|
|
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
|
{fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/component/render-graph.js
RENAMED
|
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
|
{fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/apple-touch-icon.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/favicon-16x16.png
RENAMED
|
File without changes
|
{fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/favicon-32x32.png
RENAMED
|
File without changes
|
|
File without changes
|
{fastapi_voyager-0.7.2 → fastapi_voyager-0.7.4}/src/fastapi_voyager/web/icon/site.webmanifest
RENAMED
|
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
|