qalita 2.3.2__py3-none-any.whl → 2.5.2__py3-none-any.whl
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.
- qalita/__main__.py +213 -9
- qalita/commands/{agent.py → worker.py} +89 -89
- qalita/internal/config.py +26 -19
- qalita/internal/utils.py +1 -1
- qalita/web/app.py +97 -14
- qalita/web/blueprints/context.py +13 -60
- qalita/web/blueprints/dashboard.py +35 -76
- qalita/web/blueprints/helpers.py +154 -63
- qalita/web/blueprints/sources.py +29 -61
- qalita/web/blueprints/{agents.py → workers.py} +108 -185
- qalita-2.5.2.dist-info/METADATA +66 -0
- qalita-2.5.2.dist-info/RECORD +24 -0
- {qalita-2.3.2.dist-info → qalita-2.5.2.dist-info}/WHEEL +1 -1
- qalita-2.5.2.dist-info/entry_points.txt +2 -0
- qalita/web/blueprints/studio.py +0 -1294
- qalita/web/public/chatgpt.svg +0 -3
- qalita/web/public/claude.png +0 -0
- qalita/web/public/favicon.ico +0 -0
- qalita/web/public/gemini.png +0 -0
- qalita/web/public/logo-no-slogan.png +0 -0
- qalita/web/public/logo-white-no-slogan.svg +0 -11
- qalita/web/public/mistral.svg +0 -1
- qalita/web/public/noise.webp +0 -0
- qalita/web/public/ollama.png +0 -0
- qalita/web/public/platform.png +0 -0
- qalita/web/public/sources-logos/alloy-db.png +0 -0
- qalita/web/public/sources-logos/amazon-athena.png +0 -0
- qalita/web/public/sources-logos/amazon-rds.png +0 -0
- qalita/web/public/sources-logos/api.svg +0 -2
- qalita/web/public/sources-logos/avro.svg +0 -20
- qalita/web/public/sources-logos/azure-database-mysql.png +0 -0
- qalita/web/public/sources-logos/azure-database-postgresql.png +0 -0
- qalita/web/public/sources-logos/azure-sql-database.png +0 -0
- qalita/web/public/sources-logos/azure-sql-managed-instance.png +0 -0
- qalita/web/public/sources-logos/azure-synapse-analytics.png +0 -0
- qalita/web/public/sources-logos/azure_blob.svg +0 -1
- qalita/web/public/sources-logos/bigquery.png +0 -0
- qalita/web/public/sources-logos/cassandra.svg +0 -254
- qalita/web/public/sources-logos/clickhouse.png +0 -0
- qalita/web/public/sources-logos/cloud-sql.png +0 -0
- qalita/web/public/sources-logos/cockroach-db.png +0 -0
- qalita/web/public/sources-logos/csv.svg +0 -1
- qalita/web/public/sources-logos/database.svg +0 -3
- qalita/web/public/sources-logos/databricks.png +0 -0
- qalita/web/public/sources-logos/duckdb.png +0 -0
- qalita/web/public/sources-logos/elasticsearch.svg +0 -1
- qalita/web/public/sources-logos/excel.svg +0 -1
- qalita/web/public/sources-logos/file.svg +0 -1
- qalita/web/public/sources-logos/folder.svg +0 -6
- qalita/web/public/sources-logos/gcs.png +0 -0
- qalita/web/public/sources-logos/hdfs.svg +0 -1
- qalita/web/public/sources-logos/ibm-db2.png +0 -0
- qalita/web/public/sources-logos/json.png +0 -0
- qalita/web/public/sources-logos/maria-db.png +0 -0
- qalita/web/public/sources-logos/mongodb.svg +0 -1
- qalita/web/public/sources-logos/mssql.svg +0 -1
- qalita/web/public/sources-logos/mysql.svg +0 -7
- qalita/web/public/sources-logos/oracle.svg +0 -4
- qalita/web/public/sources-logos/parquet.svg +0 -16
- qalita/web/public/sources-logos/picture.png +0 -0
- qalita/web/public/sources-logos/postgresql.svg +0 -22
- qalita/web/public/sources-logos/questdb.png +0 -0
- qalita/web/public/sources-logos/redshift.png +0 -0
- qalita/web/public/sources-logos/s3.svg +0 -34
- qalita/web/public/sources-logos/sap-hana.png +0 -0
- qalita/web/public/sources-logos/sftp.png +0 -0
- qalita/web/public/sources-logos/single-store.png +0 -0
- qalita/web/public/sources-logos/snowflake.png +0 -0
- qalita/web/public/sources-logos/sqlite.svg +0 -104
- qalita/web/public/sources-logos/sqlserver.png +0 -0
- qalita/web/public/sources-logos/starburst.png +0 -0
- qalita/web/public/sources-logos/stream.png +0 -0
- qalita/web/public/sources-logos/teradata.png +0 -0
- qalita/web/public/sources-logos/timescale.png +0 -0
- qalita/web/public/sources-logos/xls.svg +0 -1
- qalita/web/public/sources-logos/xlsx.svg +0 -1
- qalita/web/public/sources-logos/yugabyte-db.png +0 -0
- qalita/web/public/studio-logo.svg +0 -10
- qalita/web/public/studio.css +0 -304
- qalita/web/public/studio.png +0 -0
- qalita/web/public/styles.css +0 -682
- qalita/web/templates/dashboard.html +0 -373
- qalita/web/templates/navbar.html +0 -40
- qalita/web/templates/sources/added.html +0 -57
- qalita/web/templates/sources/edit.html +0 -411
- qalita/web/templates/sources/select-source.html +0 -128
- qalita/web/templates/studio/agent-panel.html +0 -828
- qalita/web/templates/studio/context-panel.html +0 -300
- qalita/web/templates/studio/index.html +0 -79
- qalita/web/templates/studio/navbar.html +0 -14
- qalita/web/templates/studio/view-panel.html +0 -529
- qalita-2.3.2.dist-info/METADATA +0 -58
- qalita-2.3.2.dist-info/RECORD +0 -101
- qalita-2.3.2.dist-info/entry_points.txt +0 -3
- {qalita-2.3.2.dist-info → qalita-2.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>QALITA CLI - Dashboard</title>
|
|
8
|
-
<link rel="icon" href="/static/favicon.ico" />
|
|
9
|
-
<link rel="stylesheet" href="/static/styles.css" />
|
|
10
|
-
</head>
|
|
11
|
-
|
|
12
|
-
<body style="background-repeat: no-repeat;">
|
|
13
|
-
{% include 'navbar.html' %}
|
|
14
|
-
|
|
15
|
-
<div class="container" style="margin-top: 0;">
|
|
16
|
-
<div class="grid equal-3" style="margin-bottom: 24px;">
|
|
17
|
-
{% if platform_url %}
|
|
18
|
-
<div>
|
|
19
|
-
<div class="platform-cta">
|
|
20
|
-
<div class="noise"></div>
|
|
21
|
-
<div class="inner">
|
|
22
|
-
<div class="header">
|
|
23
|
-
<div class="title">
|
|
24
|
-
<h3>Platform</h3>
|
|
25
|
-
</div>
|
|
26
|
-
<img src="/static/platform.png" alt="Logo Platform" width="35" height="35"
|
|
27
|
-
style="border-radius:8px;background:#fff;" />
|
|
28
|
-
</div>
|
|
29
|
-
<p>Collaborate, monitor and ensure the quality of your data assets. With Platform, you can manage your data
|
|
30
|
-
and projects in one place.</p>
|
|
31
|
-
<div>
|
|
32
|
-
<a href="{{ platform_url }}"><button class="btn cyan" type="button"
|
|
33
|
-
style="width:100%;padding:12px 16px;">Go to
|
|
34
|
-
Platform</button></a>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
{% else %}
|
|
40
|
-
<div>
|
|
41
|
-
<div class="platform-cta">
|
|
42
|
-
<div class="noise"></div>
|
|
43
|
-
<div class="inner">
|
|
44
|
-
<div class="header">
|
|
45
|
-
<div class="title">
|
|
46
|
-
<h3>Platform</h3>
|
|
47
|
-
</div>
|
|
48
|
-
<img src="/static/platform.png" alt="Logo Platform" width="35" height="35"
|
|
49
|
-
style="border-radius:8px;background:#fff;" />
|
|
50
|
-
</div>
|
|
51
|
-
<p>Collaborate, monitor and ensure the quality of your data assets. Create a free account to access Platform.</p>
|
|
52
|
-
<div>
|
|
53
|
-
<a href="https://cloud.platform.qalita.io/signup" target="_blank" rel="noopener noreferrer"><button
|
|
54
|
-
class="btn cyan" type="button" style="width:100%;padding:12px 16px;">Create a free
|
|
55
|
-
account</button></a>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
{% endif %}
|
|
61
|
-
<div>
|
|
62
|
-
<div class="studio-cta">
|
|
63
|
-
<div class="noise"></div>
|
|
64
|
-
<div class="inner">
|
|
65
|
-
<div class="header">
|
|
66
|
-
<div class="title">
|
|
67
|
-
<h3>Studio</h3>
|
|
68
|
-
<span class="badge">Alpha 0</span>
|
|
69
|
-
</div>
|
|
70
|
-
<img src="/static/studio.png" alt="Logo Studio" width="35" height="35"
|
|
71
|
-
style="border-radius:8px;background:#fff;" />
|
|
72
|
-
</div>
|
|
73
|
-
<p>Clean and improve your data at the speed of light. With Studio, take your data to the next level by
|
|
74
|
-
creating clean and corrected versions of your datasets.
|
|
75
|
-
</p>
|
|
76
|
-
<div>
|
|
77
|
-
<a href="/studio"><button class="btn blue" type="button" style="width:100%;padding:12px 16px;">Go to
|
|
78
|
-
Studio</button></a>
|
|
79
|
-
</div>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
<div class="documentation-cta">
|
|
84
|
-
<div class="noise"></div>
|
|
85
|
-
<div class="inner">
|
|
86
|
-
<div class="header">
|
|
87
|
-
<div class="title">
|
|
88
|
-
<h3>Documentation</h3>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
<p>Learn how to use QALITA and its features.</p>
|
|
92
|
-
<div>
|
|
93
|
-
<a href="https://doc.qalita.io" target="_blank" rel="noopener noreferrer"><button class="btn black-white"
|
|
94
|
-
type="button" style="width:100%;padding:12px 16px;">QALITA Docs</button></a>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
99
|
-
{% if feedback %}
|
|
100
|
-
<div class="alert {{ 'alert-error' if feedback_level == 'error' else 'alert-info' }}" style="margin-bottom:12px;">{{
|
|
101
|
-
feedback }}</div>
|
|
102
|
-
{% endif %}
|
|
103
|
-
<div class="grid">
|
|
104
|
-
<div>
|
|
105
|
-
<div style="display:flex;align-items:center; gap:12px;">
|
|
106
|
-
<h2>Sources</h2>
|
|
107
|
-
<div class="actions mb-12">
|
|
108
|
-
<a class="btn" href="/sources/add">Add source</a>
|
|
109
|
-
<form class="inline" method="post" action="/validate" style="display:inline;">
|
|
110
|
-
<button class="btn secondary" type="submit">Validate</button>
|
|
111
|
-
</form>
|
|
112
|
-
<form class="inline" method="post" action="/push" style="display:inline;">
|
|
113
|
-
<button class="btn secondary" type="submit">Push</button>
|
|
114
|
-
</form>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
<div class="card">
|
|
118
|
-
<table>
|
|
119
|
-
<thead>
|
|
120
|
-
<tr>
|
|
121
|
-
<th>Name</th>
|
|
122
|
-
<th>Type</th>
|
|
123
|
-
<th>Visibility</th>
|
|
124
|
-
<th>Check</th>
|
|
125
|
-
</tr>
|
|
126
|
-
</thead>
|
|
127
|
-
<tbody>
|
|
128
|
-
{% for s in sources %}
|
|
129
|
-
{% set icon_map = {
|
|
130
|
-
'file':'file.svg', 'csv':'csv.svg', 'excel':'excel.svg', 'folder':'folder.svg',
|
|
131
|
-
'postgresql':'postgresql.svg', 'mysql':'mysql.svg',
|
|
132
|
-
'oracle':'oracle.svg', 'mssql':'mssql.svg',
|
|
133
|
-
'sqlite':'sqlite.svg', 'mongodb':'mongodb.svg', 's3':'s3.svg', 'gcs':'gcs.png',
|
|
134
|
-
'azure_blob':'azure_blob.svg', 'hdfs':'hdfs.svg',
|
|
135
|
-
} %}
|
|
136
|
-
{% set type_icon = icon_map.get(s.type, 'folder.svg') %}
|
|
137
|
-
<tr>
|
|
138
|
-
<td>
|
|
139
|
-
{% set _id = s.get('id') %}
|
|
140
|
-
{% if _id and platform_url %}
|
|
141
|
-
<a href="{{ platform_url.rstrip('/') }}/home/data-engineering/sources/{{ _id }}" target="_blank"
|
|
142
|
-
rel="noopener noreferrer">{{ s.name }}</a>
|
|
143
|
-
{% else %}
|
|
144
|
-
{{ s.name }}
|
|
145
|
-
{% endif %}
|
|
146
|
-
{% if s.description %}
|
|
147
|
-
<div class="subtle">{{ s.description }}</div>
|
|
148
|
-
{% endif %}
|
|
149
|
-
</td>
|
|
150
|
-
<td>
|
|
151
|
-
<div style="display:flex;align-items:center;gap:6px;">
|
|
152
|
-
<img src="/static/sources-logos/{{ type_icon }}" alt="{{ s.type }}"
|
|
153
|
-
style="height:20px;max-width:30px;border-radius:4px;" />
|
|
154
|
-
<span>{{ s.type }}</span>
|
|
155
|
-
</div>
|
|
156
|
-
</td>
|
|
157
|
-
{% set vis = (s.visibility or '')|lower %}
|
|
158
|
-
<td>
|
|
159
|
-
{% if vis == 'private' %}
|
|
160
|
-
<span title="private" class="badge badge-private">
|
|
161
|
-
<svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
162
|
-
<rect x="3" y="9" width="14" height="8" rx="2" stroke="#374151" stroke-width="2" />
|
|
163
|
-
<path d="M6 9V7a4 4 0 1 1 8 0v2" stroke="#374151" stroke-width="2" fill="none" />
|
|
164
|
-
</svg>
|
|
165
|
-
Private
|
|
166
|
-
</span>
|
|
167
|
-
{% elif vis == 'internal' %}
|
|
168
|
-
<span title="internal" class="badge badge-internal">
|
|
169
|
-
<svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
170
|
-
<rect x="3" y="6" width="14" height="10" rx="2" stroke="#0ea5e9" stroke-width="2" />
|
|
171
|
-
<path d="M7 6V4h6v2" stroke="#0ea5e9" stroke-width="2" />
|
|
172
|
-
</svg>
|
|
173
|
-
Internal
|
|
174
|
-
</span>
|
|
175
|
-
{% elif vis == 'public' %}
|
|
176
|
-
<span title="public" class="badge badge-public">
|
|
177
|
-
<svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
178
|
-
<circle cx="10" cy="10" r="8" stroke="#16a34a" stroke-width="2" />
|
|
179
|
-
<path d="M2 10h16M10 2a12 12 0 0 1 0 16M10 2a12 12 0 0 0 0 16" stroke="#16a34a"
|
|
180
|
-
stroke-width="2" />
|
|
181
|
-
</svg>
|
|
182
|
-
Public
|
|
183
|
-
</span>
|
|
184
|
-
{% else %}
|
|
185
|
-
<span class="muted">{{ s.visibility }}</span>
|
|
186
|
-
{% endif %}
|
|
187
|
-
</td>
|
|
188
|
-
{% set val = (s.validate or '')|lower %}
|
|
189
|
-
<td>
|
|
190
|
-
{% if val == 'valid' %}
|
|
191
|
-
<span title="valid" class="badge badge-valid">
|
|
192
|
-
<svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
193
|
-
<circle cx="10" cy="10" r="9" stroke="#059669" stroke-width="2" />
|
|
194
|
-
<path d="M6 10.5l2.5 2.5L14 7.5" stroke="#059669" stroke-width="2" fill="none"
|
|
195
|
-
stroke-linecap="round" stroke-linejoin="round" />
|
|
196
|
-
</svg>
|
|
197
|
-
Reachable
|
|
198
|
-
</span>
|
|
199
|
-
{% elif val == 'invalid' %}
|
|
200
|
-
<span title="invalid" class="badge badge-invalid">
|
|
201
|
-
<svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
202
|
-
<circle cx="10" cy="10" r="9" stroke="#b91c1c" stroke-width="2" />
|
|
203
|
-
<path d="M7 7l6 6M13 7l-6 6" stroke="#b91c1c" stroke-width="2" stroke-linecap="round" />
|
|
204
|
-
</svg>
|
|
205
|
-
Unreachable
|
|
206
|
-
</span>
|
|
207
|
-
{% else %}
|
|
208
|
-
<span class="muted">{{ s.validate or '' }}</span>
|
|
209
|
-
{% endif %}
|
|
210
|
-
</td>
|
|
211
|
-
<td class="muted"></td>
|
|
212
|
-
<td>
|
|
213
|
-
<div class="actions">
|
|
214
|
-
<a class="btn secondary" href="/sources/edit/{{ s.name }}">Edit</a>
|
|
215
|
-
<form class="inline" method="post" action="/sources/delete/{{ s.name }}"
|
|
216
|
-
onsubmit="return confirm('Delete this source?');" style="display:inline;">
|
|
217
|
-
<button class="btn danger" type="submit">Delete</button>
|
|
218
|
-
</form>
|
|
219
|
-
</div>
|
|
220
|
-
</td>
|
|
221
|
-
</tr>
|
|
222
|
-
{% endfor %}
|
|
223
|
-
</tbody>
|
|
224
|
-
</table>
|
|
225
|
-
</div>
|
|
226
|
-
</div>
|
|
227
|
-
<div style="margin-top: 12px;">
|
|
228
|
-
<div style="display:flex;align-items:center; gap: 10px;">
|
|
229
|
-
<h2>Agent</h2>
|
|
230
|
-
<div style="display:flex;gap:20px;align-items:center;">
|
|
231
|
-
<div id="agent_switch"
|
|
232
|
-
style="margin-top: -11px; position:relative;width:46px;height:26px;background:#e5e7eb;border-radius:9999px;cursor:pointer;display:inline-block;transition:background .15s ease;">
|
|
233
|
-
<div id="agent_knob"
|
|
234
|
-
style="position:absolute;top:3px;left:3px;width:20px;height:20px;background:#ffffff;border-radius:35%;box-shadow:0 1px 3px rgba(0,0,0,.2);transition:left .15s ease;">
|
|
235
|
-
</div>
|
|
236
|
-
</div>
|
|
237
|
-
<input id="agent_toggle" type="checkbox" class="hidden" />
|
|
238
|
-
<span id="agent_state" class="muted" style="margin-top: -13px;"></span>
|
|
239
|
-
</div>
|
|
240
|
-
</div>
|
|
241
|
-
<div class="card" style="margin-bottom: 24px;">
|
|
242
|
-
{% if agent_conf %}
|
|
243
|
-
<div style="display:grid;grid-template-columns: 160px 1fr;row-gap:8px;column-gap:12px;">
|
|
244
|
-
<div class="muted">Name</div>
|
|
245
|
-
<div data-agent-name>
|
|
246
|
-
{% if platform_url %}
|
|
247
|
-
<a href="{{ platform_url.rstrip('/') }}/home/data-engineering/agents/?agent={{ agent_conf.get('name','') }}"
|
|
248
|
-
target="_blank" rel="noopener noreferrer">{{ agent_conf.get('name','') }}</a>
|
|
249
|
-
{% else %}
|
|
250
|
-
{{ agent_conf.get('name','') }}
|
|
251
|
-
{% endif %}
|
|
252
|
-
</div>
|
|
253
|
-
<div class="muted">Mode</div>
|
|
254
|
-
<div data-agent-mode>{{ agent_conf.get('mode','') }}</div>
|
|
255
|
-
<div class="muted">Backend URL</div>
|
|
256
|
-
<div data-agent-url><a href="{{ agent_conf.get('url','') }}" target="_blank" rel="noopener noreferrer">{{
|
|
257
|
-
agent_conf.get('url','') }}</a></div>
|
|
258
|
-
<div class="muted">Agent ID</div>
|
|
259
|
-
<div data-agent-id>{{ agent_conf.get('agent_id','') }}</div>
|
|
260
|
-
</div>
|
|
261
|
-
<div style="margin-top:12px;">
|
|
262
|
-
<div class="muted" style="margin-bottom:6px;">Agent Runs</div>
|
|
263
|
-
{% set list_runs = agent_runs_page if agent_runs_page is defined else (agent_runs[:10] if agent_runs is
|
|
264
|
-
defined else []) %}
|
|
265
|
-
{% if list_runs and list_runs|length > 0 %}
|
|
266
|
-
<ul style="margin:0;padding-left:18px;">
|
|
267
|
-
{% for r in list_runs %}
|
|
268
|
-
<li><span class="muted">{{ r.when }}</span> —
|
|
269
|
-
<code><a href="/agent/run/{{ r.name }}" target="_blank" rel="noopener noreferrer">{{ r.name }}</a></code>
|
|
270
|
-
</li>
|
|
271
|
-
{% endfor %}
|
|
272
|
-
</ul>
|
|
273
|
-
<div style="display:flex;align-items:center;justify-content:space-between;margin-top:8px;">
|
|
274
|
-
<div class="muted">
|
|
275
|
-
{% if runs_start is defined and runs_end is defined and runs_total is defined %}
|
|
276
|
-
Showing {{ runs_start }}–{{ runs_end }} of {{ runs_total }}
|
|
277
|
-
{% else %}
|
|
278
|
-
Showing {{ (list_runs|length) }} recent run(s)
|
|
279
|
-
{% endif %}
|
|
280
|
-
</div>
|
|
281
|
-
<div class="actions" style="display:flex;gap:8px;">
|
|
282
|
-
{% set cur_page = runs_page if runs_page is defined else 1 %}
|
|
283
|
-
{% set per_page = runs_per_page if runs_per_page is defined else 10 %}
|
|
284
|
-
{% if runs_has_prev %}
|
|
285
|
-
<a class="btn secondary" href="/?runs_page={{ cur_page - 1 }}&runs_per_page={{ per_page }}">Prev</a>
|
|
286
|
-
{% else %}
|
|
287
|
-
<button class="btn secondary" disabled>Prev</button>
|
|
288
|
-
{% endif %}
|
|
289
|
-
{% if runs_has_next %}
|
|
290
|
-
<a class="btn secondary" href="/?runs_page={{ cur_page + 1 }}&runs_per_page={{ per_page }}">Next</a>
|
|
291
|
-
{% else %}
|
|
292
|
-
<button class="btn secondary" disabled>Next</button>
|
|
293
|
-
{% endif %}
|
|
294
|
-
</div>
|
|
295
|
-
</div>
|
|
296
|
-
{% else %}
|
|
297
|
-
<div class="muted">No runs found.</div>
|
|
298
|
-
{% endif %}
|
|
299
|
-
</div>
|
|
300
|
-
{% else %}
|
|
301
|
-
<div class="muted">No agent configuration found. Use "qalita agent login" to configure.</div>
|
|
302
|
-
{% endif %}
|
|
303
|
-
</div>
|
|
304
|
-
{% if platform_url %}
|
|
305
|
-
<h2>Pack</h2>
|
|
306
|
-
<div class="card" style="margin-bottom: 24px;">
|
|
307
|
-
<form method="post" action="/pack/push">
|
|
308
|
-
<label for="pack_dir">Pack folder</label>
|
|
309
|
-
<div class="row" style="display:grid;grid-template-columns:1fr auto;gap:8px;align-items:center;">
|
|
310
|
-
<input id="pack_dir" name="pack_dir" type="text" placeholder="/path/to/your_pack" />
|
|
311
|
-
<button type="button" class="btn secondary" style="margin-top: 5px;" id="browse_pack">Browse…</button>
|
|
312
|
-
</div>
|
|
313
|
-
<div class="actions" style="margin-top:12px;">
|
|
314
|
-
<button class="btn" type="submit">Push Pack</button>
|
|
315
|
-
</div>
|
|
316
|
-
</form>
|
|
317
|
-
</div>
|
|
318
|
-
{% endif %}
|
|
319
|
-
</div>
|
|
320
|
-
</div>
|
|
321
|
-
</div>
|
|
322
|
-
<div class="footer">
|
|
323
|
-
<div class="inner">
|
|
324
|
-
<div>
|
|
325
|
-
<span>© QALITA</span> — QALITA CLI
|
|
326
|
-
</div>
|
|
327
|
-
<div>
|
|
328
|
-
<span id="cli_version"></span>
|
|
329
|
-
</div>
|
|
330
|
-
</div>
|
|
331
|
-
</div>
|
|
332
|
-
<script>
|
|
333
|
-
(function () {
|
|
334
|
-
fetch('/static/version.json').then(r => r.json()).then(v => {
|
|
335
|
-
const el = document.getElementById('cli_version'); if (el) { el.textContent = (v && v.version) ? `CLI v${v.version}` : ''; }
|
|
336
|
-
}).catch(() => { });
|
|
337
|
-
})();
|
|
338
|
-
(function () {
|
|
339
|
-
function pickFolder() {
|
|
340
|
-
fetch('/sources/pick-folder').then(r => r.json()).then(j => {
|
|
341
|
-
if (j && j.path) { var inp = document.getElementById('pack_dir'); if (inp) { inp.value = j.path; } }
|
|
342
|
-
}).catch(() => { });
|
|
343
|
-
}
|
|
344
|
-
var btn = document.getElementById('browse_pack'); if (btn) { btn.addEventListener('click', pickFolder); }
|
|
345
|
-
})();
|
|
346
|
-
(function () {
|
|
347
|
-
const toggle = document.getElementById('agent_toggle');
|
|
348
|
-
const label = document.getElementById('agent_state');
|
|
349
|
-
const sw = document.getElementById('agent_switch');
|
|
350
|
-
const knob = document.getElementById('agent_knob');
|
|
351
|
-
if (!toggle) return;
|
|
352
|
-
function refresh() {
|
|
353
|
-
fetch('/agent/status').then(r => r.json()).then(j => {
|
|
354
|
-
const running = !!(j && j.running);
|
|
355
|
-
toggle.checked = running;
|
|
356
|
-
if (label) { label.textContent = running ? '(running)' : '(stopped)'; }
|
|
357
|
-
if (sw) { sw.style.background = running ? '#16a34a' : '#e5e7eb'; }
|
|
358
|
-
if (knob) { knob.style.left = running ? '23px' : '3px'; }
|
|
359
|
-
}).catch(() => { if (label) { label.textContent = '(unknown)'; } });
|
|
360
|
-
}
|
|
361
|
-
function setState(isOn) {
|
|
362
|
-
fetch(isOn ? '/agent/start' : '/agent/stop', { method: 'POST' })
|
|
363
|
-
.then(() => refresh())
|
|
364
|
-
.catch(() => refresh());
|
|
365
|
-
}
|
|
366
|
-
toggle.addEventListener('change', function () { setState(toggle.checked); });
|
|
367
|
-
if (sw) { sw.addEventListener('click', function () { toggle.checked = !toggle.checked; setState(toggle.checked); }); }
|
|
368
|
-
refresh();
|
|
369
|
-
})();
|
|
370
|
-
</script>
|
|
371
|
-
</body>
|
|
372
|
-
|
|
373
|
-
</html>
|
qalita/web/templates/navbar.html
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<div class="topbar">
|
|
2
|
-
<div class="brand">
|
|
3
|
-
<div class="left">
|
|
4
|
-
<a href="/" style="display:flex;align-items:center;gap:8px;text-decoration:none;color:inherit;">
|
|
5
|
-
<img src="/static/logo-no-slogan.png" alt="QALITA" />
|
|
6
|
-
<span>CLI</span>
|
|
7
|
-
</a>
|
|
8
|
-
</div>
|
|
9
|
-
<div class="right" style="display:flex;align-items:center;gap:8px;">
|
|
10
|
-
<p style="margin: 0px; ">Context</p>
|
|
11
|
-
<select id="ctx_select" class="ctx-select" style="margin-top: 0px; cursor:pointer;"></select>
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
|
-
</div>
|
|
15
|
-
<script>
|
|
16
|
-
(function () {
|
|
17
|
-
function loadContexts() {
|
|
18
|
-
fetch('/contexts').then(r => r.json()).then(j => {
|
|
19
|
-
var sel = document.getElementById('ctx_select'); if (!sel) return;
|
|
20
|
-
sel.innerHTML = '';
|
|
21
|
-
var opt = document.createElement('option');
|
|
22
|
-
opt.value = ''; opt.textContent = 'Default context'; sel.appendChild(opt);
|
|
23
|
-
(j.items || []).forEach(function (it) {
|
|
24
|
-
var o = document.createElement('option');
|
|
25
|
-
o.value = it.path; o.textContent = it.name; sel.appendChild(o);
|
|
26
|
-
});
|
|
27
|
-
if (j.selected) { sel.value = j.selected; }
|
|
28
|
-
}).catch(() => { });
|
|
29
|
-
}
|
|
30
|
-
function onSelect() {
|
|
31
|
-
var sel = document.getElementById('ctx_select'); if (!sel) return;
|
|
32
|
-
fetch('/context/select', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ path: sel.value }) })
|
|
33
|
-
.then(() => { window.location.reload(); })
|
|
34
|
-
.catch(() => { window.location.reload(); });
|
|
35
|
-
}
|
|
36
|
-
document.addEventListener('DOMContentLoaded', function () {
|
|
37
|
-
loadContexts(); var sel = document.getElementById('ctx_select'); if (sel) sel.addEventListener('change', onSelect);
|
|
38
|
-
});
|
|
39
|
-
})();
|
|
40
|
-
</script>
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>QALITA CLI - Source added</title>
|
|
8
|
-
<link rel="icon" href="/static/favicon.ico" />
|
|
9
|
-
<link rel="stylesheet" href="/static/styles.css" />
|
|
10
|
-
</head>
|
|
11
|
-
|
|
12
|
-
<body style="background-repeat: no-repeat;">
|
|
13
|
-
{% include 'navbar.html' %}
|
|
14
|
-
<div class="container-form">
|
|
15
|
-
<h1>Source added</h1>
|
|
16
|
-
<div class="card">
|
|
17
|
-
<p>Your source <strong>{{ name }}</strong> has been added successfully.</p>
|
|
18
|
-
{% if platform_url %}
|
|
19
|
-
<p>You can now go to the Platform to view the source reference and schedule analyses.</p>
|
|
20
|
-
<div class="actions" style="margin-top: 12px;">
|
|
21
|
-
{% if source_id %}
|
|
22
|
-
<a class="btn cyan" href="{{ platform_url.rstrip('/') }}/home/data-engineering/sources/{{ source_id }}" target="_blank" rel="noopener noreferrer">Open in Platform</a>
|
|
23
|
-
{% else %}
|
|
24
|
-
<a class="btn cyan" href="{{ platform_url }}" target="_blank" rel="noopener noreferrer">Open Platform</a>
|
|
25
|
-
{% endif %}
|
|
26
|
-
<a class="btn secondary" href="/">Back to Dashboard</a>
|
|
27
|
-
</div>
|
|
28
|
-
{% else %}
|
|
29
|
-
<p class="muted">Platform URL is not configured. Configure the agent or set the URL to access Platform.</p>
|
|
30
|
-
<div class="actions" style="margin-top: 12px;">
|
|
31
|
-
<a class="btn" href="/">Back to Dashboard</a>
|
|
32
|
-
</div>
|
|
33
|
-
{% endif %}
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
<div class="footer">
|
|
37
|
-
<div class="inner">
|
|
38
|
-
<div>
|
|
39
|
-
<span>© QALITA</span> — QALITA CLI
|
|
40
|
-
</div>
|
|
41
|
-
<div>
|
|
42
|
-
<span id="cli_version"></span>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
<script>
|
|
47
|
-
(function () {
|
|
48
|
-
fetch('/static/version.json').then(r => r.json()).then(v => {
|
|
49
|
-
const el = document.getElementById('cli_version'); if (el) { el.textContent = (v && v.version) ? `CLI v${v.version}` : ''; }
|
|
50
|
-
}).catch(() => { });
|
|
51
|
-
})();
|
|
52
|
-
</script>
|
|
53
|
-
</body>
|
|
54
|
-
|
|
55
|
-
</html>
|
|
56
|
-
|
|
57
|
-
|