qalita 2.2.8__py3-none-any.whl → 2.3.0__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 +3 -3
- qalita/commands/agent.py +10 -10
- qalita/commands/pack.py +6 -6
- qalita/commands/source.py +4 -4
- qalita/internal/utils.py +1 -1
- qalita/web/app.py +2 -2
- qalita/web/blueprints/agents.py +3 -3
- qalita/web/public/studio.css +13 -5
- qalita/web/templates/dashboard.html +4 -4
- qalita/web/templates/navbar.html +1 -1
- qalita/web/templates/sources/added.html +2 -2
- qalita/web/templates/sources/edit.html +2 -2
- qalita/web/templates/sources/select-source.html +3 -3
- qalita/web/templates/studio/context-panel.html +18 -5
- qalita/web/templates/studio/index.html +4 -4
- qalita/web/templates/studio/navbar.html +2 -2
- qalita/web/templates/studio/view-panel.html +130 -22
- {qalita-2.2.8.dist-info → qalita-2.3.0.dist-info}/METADATA +4 -2
- {qalita-2.2.8.dist-info → qalita-2.3.0.dist-info}/RECORD +22 -22
- {qalita-2.2.8.dist-info → qalita-2.3.0.dist-info}/WHEEL +1 -1
- {qalita-2.2.8.dist-info → qalita-2.3.0.dist-info}/entry_points.txt +0 -0
- {qalita-2.2.8.dist-info → qalita-2.3.0.dist-info/licenses}/LICENSE +0 -0
qalita/__main__.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import os
|
|
5
5
|
import click
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
from qalita.internal.utils import logger, get_version
|
|
8
8
|
from qalita.internal.config import Config
|
|
9
9
|
|
|
@@ -37,8 +37,8 @@ pass_config = click.make_pass_decorator(Config, ensure=True)
|
|
|
37
37
|
@click.pass_context
|
|
38
38
|
def cli(ctx, ui=False, port=7070, host="localhost"):
|
|
39
39
|
"""
|
|
40
|
-
------------------
|
|
41
|
-
Hello and thanks for using
|
|
40
|
+
------------------ QALITA Platform Command Line Interface ------------------\n\r
|
|
41
|
+
Hello and thanks for using QALITA Platform to monitor and ensure the quality of your data. \n\r
|
|
42
42
|
----------------------------------------------------------------------------\n\r
|
|
43
43
|
Please, Help us improve our service by reporting any bug by filing a bug report, Thanks ! \n\r
|
|
44
44
|
mail : contact@qalita.io \n\r
|
qalita/commands/agent.py
CHANGED
|
@@ -56,7 +56,7 @@ ROUTINE_LAST_SCHEDULED_UTC = {}
|
|
|
56
56
|
)
|
|
57
57
|
@pass_config
|
|
58
58
|
def agent(config, name, mode, token, url):
|
|
59
|
-
"""Manage
|
|
59
|
+
"""Manage QALITA Platform Agents"""
|
|
60
60
|
|
|
61
61
|
all_check_pass = True
|
|
62
62
|
|
|
@@ -200,7 +200,7 @@ def send_alive(config, config_file, mode="", status="online"):
|
|
|
200
200
|
|
|
201
201
|
@pass_config
|
|
202
202
|
def authenticate(config, user_id):
|
|
203
|
-
"""Authenticate the agent to the
|
|
203
|
+
"""Authenticate the agent to the QALITA Platform"""
|
|
204
204
|
try:
|
|
205
205
|
r = send_request.__wrapped__(
|
|
206
206
|
config,
|
|
@@ -345,7 +345,7 @@ def authenticate(config, user_id):
|
|
|
345
345
|
@pass_config
|
|
346
346
|
def login(config):
|
|
347
347
|
"""
|
|
348
|
-
Register the agent to the
|
|
348
|
+
Register the agent to the QALITA Platform
|
|
349
349
|
"""
|
|
350
350
|
if config.verbose:
|
|
351
351
|
logger.info("Verbose mode enabled")
|
|
@@ -356,8 +356,8 @@ def login(config):
|
|
|
356
356
|
r = send_request(request=f"{config.url}/api/v1/version", mode="get")
|
|
357
357
|
if r.status_code == 200:
|
|
358
358
|
if r.json()["version"] != get_version():
|
|
359
|
-
logger.info(f"
|
|
360
|
-
logger.info(f"
|
|
359
|
+
logger.info(f"QALITA Platform Version : {r.json()['version']}")
|
|
360
|
+
logger.info(f"QALITA CLI Version : {get_version()}")
|
|
361
361
|
logger.info(
|
|
362
362
|
"Make sure you are using compatible versions for the platform and the cli,\n\t> check compatibility matrix on the documentation <"
|
|
363
363
|
)
|
|
@@ -874,7 +874,7 @@ def post_run(
|
|
|
874
874
|
## LOGS
|
|
875
875
|
# Initialize logs_id to None
|
|
876
876
|
logs_id = None
|
|
877
|
-
logger.info(f"Uploading logs to
|
|
877
|
+
logger.info(f"Uploading logs to QALITA Platform...")
|
|
878
878
|
logger.info(f"run_path: {run_path}")
|
|
879
879
|
if os.path.exists(run_path + "/logs.txt"):
|
|
880
880
|
api_url = agent_conf["context"]["local"]["url"]
|
|
@@ -912,12 +912,12 @@ def post_run(
|
|
|
912
912
|
else:
|
|
913
913
|
logger.info(f"No logs.txt file found")
|
|
914
914
|
|
|
915
|
-
logger.info(f"Uploading results to
|
|
915
|
+
logger.info(f"Uploading results to QALITA Platform...")
|
|
916
916
|
|
|
917
917
|
#########################################################
|
|
918
918
|
## Recommendations
|
|
919
919
|
if os.path.exists(run_path + "/recommendations.json"):
|
|
920
|
-
logger.info(f"\tUploading recommendations to
|
|
920
|
+
logger.info(f"\tUploading recommendations to QALITA Platform...")
|
|
921
921
|
|
|
922
922
|
api_url = agent_conf["context"]["local"]["url"]
|
|
923
923
|
registry_id = agent_conf["registries"][0]["id"]
|
|
@@ -949,7 +949,7 @@ def post_run(
|
|
|
949
949
|
#########################################################
|
|
950
950
|
## Schemas
|
|
951
951
|
if os.path.exists(run_path + "/schemas.json"):
|
|
952
|
-
logger.info(f"\tUploading schemas to
|
|
952
|
+
logger.info(f"\tUploading schemas to QALITA Platform...")
|
|
953
953
|
|
|
954
954
|
api_url = agent_conf["context"]["local"]["url"]
|
|
955
955
|
registry_id = agent_conf["registries"][0]["id"]
|
|
@@ -981,7 +981,7 @@ def post_run(
|
|
|
981
981
|
#########################################################
|
|
982
982
|
## Metrics
|
|
983
983
|
if os.path.exists(run_path + "/metrics.json"):
|
|
984
|
-
logger.info(f"\tUploading Metrics to
|
|
984
|
+
logger.info(f"\tUploading Metrics to QALITA Platform...")
|
|
985
985
|
|
|
986
986
|
api_url = agent_conf["context"]["local"]["url"]
|
|
987
987
|
registry_id = agent_conf["registries"][0]["id"]
|
qalita/commands/pack.py
CHANGED
|
@@ -241,7 +241,7 @@ def check_name(name):
|
|
|
241
241
|
@click.option("-p", "--pack", type=int, help="Pack ID")
|
|
242
242
|
@click.pass_context
|
|
243
243
|
def pack(ctx, pack):
|
|
244
|
-
"""Manage
|
|
244
|
+
"""Manage QALITA Platform Packs"""
|
|
245
245
|
ctx.ensure_object(dict)
|
|
246
246
|
ctx.obj["PACK"] = pack
|
|
247
247
|
|
|
@@ -416,7 +416,7 @@ def validate_pack_directory(pack_directory: str) -> int:
|
|
|
416
416
|
@click.option(
|
|
417
417
|
"-n",
|
|
418
418
|
"--name",
|
|
419
|
-
help="The name of the package, it will be used to identify the package in the
|
|
419
|
+
help="The name of the package, it will be used to identify the package in the QALITA platform",
|
|
420
420
|
envvar="QALITA_PACK_NAME",
|
|
421
421
|
)
|
|
422
422
|
@pass_config
|
|
@@ -693,7 +693,7 @@ def handle_version_matching(existing_versions, new_version):
|
|
|
693
693
|
@click.option("-n", "--name", help="Name of the package", envvar="QALITA_PACK_NAME")
|
|
694
694
|
@pass_config
|
|
695
695
|
def push(config, name):
|
|
696
|
-
"""Pushes a package to the
|
|
696
|
+
"""Pushes a package to the QALITA Platform"""
|
|
697
697
|
|
|
698
698
|
try:
|
|
699
699
|
name = check_name(name)
|
|
@@ -709,7 +709,7 @@ def push(config, name):
|
|
|
709
709
|
return
|
|
710
710
|
|
|
711
711
|
logger.info("---------------- Pack Push ----------------")
|
|
712
|
-
logger.info(f"Pushing pack '{name}' to
|
|
712
|
+
logger.info(f"Pushing pack '{name}' to QALITA Platform...")
|
|
713
713
|
|
|
714
714
|
pack_directory = f"./{name}_pack" if not name.endswith("_pack") else f"./{name}"
|
|
715
715
|
|
|
@@ -920,7 +920,7 @@ def push_from_directory(config, pack_directory):
|
|
|
920
920
|
@click.option(
|
|
921
921
|
"-n",
|
|
922
922
|
"--name",
|
|
923
|
-
help="The name of the package, it will be used to identify the package in the
|
|
923
|
+
help="The name of the package, it will be used to identify the package in the QALITA platform",
|
|
924
924
|
envvar="QALITA_PACK_NAME",
|
|
925
925
|
)
|
|
926
926
|
def run(name):
|
|
@@ -969,7 +969,7 @@ def run(name):
|
|
|
969
969
|
@click.option(
|
|
970
970
|
"-n",
|
|
971
971
|
"--name",
|
|
972
|
-
help="The name of the package, it will be used to identify the package in the
|
|
972
|
+
help="The name of the package, it will be used to identify the package in the QALITA platform",
|
|
973
973
|
envvar="QALITA_PACK_NAME",
|
|
974
974
|
)
|
|
975
975
|
@pass_config
|
qalita/commands/source.py
CHANGED
|
@@ -15,7 +15,7 @@ from qalita.internal.request import send_api_request
|
|
|
15
15
|
@click.option("-s", "--source", type=int, help="Source ID")
|
|
16
16
|
@click.pass_context
|
|
17
17
|
def source(ctx, source):
|
|
18
|
-
"""Manage
|
|
18
|
+
"""Manage QALITA Platform Sources"""
|
|
19
19
|
ctx.ensure_object(dict)
|
|
20
20
|
ctx.obj["SOURCE"] = source
|
|
21
21
|
|
|
@@ -264,13 +264,13 @@ def validate():
|
|
|
264
264
|
)
|
|
265
265
|
@pass_config
|
|
266
266
|
def push(config, skip_validate):
|
|
267
|
-
"""Publish a source to the
|
|
267
|
+
"""Publish a source to the QALITA Platform"""
|
|
268
268
|
if not skip_validate:
|
|
269
269
|
validate_source()
|
|
270
270
|
else:
|
|
271
271
|
logger.warning("Skipping source validation as requested.")
|
|
272
272
|
logger.info("------------- Source Publishing -------------")
|
|
273
|
-
logger.info("Publishing sources to the
|
|
273
|
+
logger.info("Publishing sources to the QALITA Platform...")
|
|
274
274
|
|
|
275
275
|
invalid_count = 0 # To count failed publishing sources
|
|
276
276
|
agent_conf = config.load_agent_config()
|
|
@@ -638,7 +638,7 @@ def push_single_programmatic(config, source_name: str, approve_public: bool = Fa
|
|
|
638
638
|
@source.command()
|
|
639
639
|
@pass_config
|
|
640
640
|
def add(config):
|
|
641
|
-
"""Add a source to the local
|
|
641
|
+
"""Add a source to the local QALITA Config"""
|
|
642
642
|
|
|
643
643
|
# initialize the source dict
|
|
644
644
|
source = {}
|
qalita/internal/utils.py
CHANGED
qalita/web/app.py
CHANGED
|
@@ -7,7 +7,7 @@ from flask import Flask
|
|
|
7
7
|
from waitress import serve
|
|
8
8
|
|
|
9
9
|
def create_app(config_obj) -> Flask:
|
|
10
|
-
"""Application factory for the
|
|
10
|
+
"""Application factory for the QALITA CLI UI."""
|
|
11
11
|
app = Flask(
|
|
12
12
|
__name__,
|
|
13
13
|
static_folder=os.path.join(os.path.dirname(__file__), "public"),
|
|
@@ -36,5 +36,5 @@ def create_app(config_obj) -> Flask:
|
|
|
36
36
|
def run_dashboard_ui(config_obj, host: str = "localhost", port: int = 7070):
|
|
37
37
|
app = create_app(config_obj)
|
|
38
38
|
url = f"http://{host}:{port}"
|
|
39
|
-
print(f"
|
|
39
|
+
print(f"QALITA CLI UI is running. Open {url}")
|
|
40
40
|
serve(app, host=host, port=port)
|
qalita/web/blueprints/agents.py
CHANGED
|
@@ -375,7 +375,7 @@ def open_agent_run(run_name: str):
|
|
|
375
375
|
<div class="footer">
|
|
376
376
|
<div class="inner">
|
|
377
377
|
<div>
|
|
378
|
-
<span>© QALITA</span> —
|
|
378
|
+
<span>© QALITA</span> — QALITA CLI
|
|
379
379
|
</div>
|
|
380
380
|
<div>
|
|
381
381
|
<span id="cli_version"></span>
|
|
@@ -411,7 +411,7 @@ def open_agent_run(run_name: str):
|
|
|
411
411
|
<div class="footer">
|
|
412
412
|
<div class="inner">
|
|
413
413
|
<div>
|
|
414
|
-
<span>© QALITA</span> —
|
|
414
|
+
<span>© QALITA</span> — QALITA CLI
|
|
415
415
|
</div>
|
|
416
416
|
<div>
|
|
417
417
|
<span id="cli_version"></span>
|
|
@@ -451,7 +451,7 @@ def open_agent_run(run_name: str):
|
|
|
451
451
|
<div class="footer">
|
|
452
452
|
<div class="inner">
|
|
453
453
|
<div>
|
|
454
|
-
<span>© QALITA</span> —
|
|
454
|
+
<span>© QALITA</span> — QALITA CLI
|
|
455
455
|
</div>
|
|
456
456
|
<div>
|
|
457
457
|
<span id="cli_version"></span>
|
qalita/web/public/studio.css
CHANGED
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
--studio-primary: #4169e1;
|
|
4
4
|
/* royal blue */
|
|
5
5
|
--studio-primary-600: #3657c7;
|
|
6
|
-
--studio-bg: #
|
|
6
|
+
--studio-bg: #f3f7ff;
|
|
7
7
|
--studio-surface: #12161c;
|
|
8
|
-
--studio-surface-2: #
|
|
8
|
+
--studio-surface-2: #9b9b9b;
|
|
9
9
|
--studio-border: #1e2633;
|
|
10
|
+
--studio-border-2: #283242;
|
|
10
11
|
--studio-text: #3a3d43;
|
|
11
12
|
--studio-muted: #9ca3af;
|
|
12
13
|
--studio-accent: #4169e1;
|
|
13
14
|
color: var(--studio-text);
|
|
14
|
-
background: linear-gradient(180deg, var(--studio-bg), var(--studio-surface));
|
|
15
15
|
min-height: 100vh;
|
|
16
16
|
display: flex;
|
|
17
17
|
flex-direction: column;
|
|
@@ -53,9 +53,14 @@
|
|
|
53
53
|
.studio .card {
|
|
54
54
|
background: var(--studio-surface);
|
|
55
55
|
border-color: var(--studio-border);
|
|
56
|
-
box-shadow: 0 2px 14px rgba(0, 0, 0, .25);
|
|
57
56
|
}
|
|
58
57
|
|
|
58
|
+
.studio .card:hover {
|
|
59
|
+
background: var(--studio-surface-2);
|
|
60
|
+
border-color: var(--studio-border-2);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
59
64
|
/* Buttons */
|
|
60
65
|
.studio .btn,
|
|
61
66
|
.studio-btn {
|
|
@@ -135,6 +140,9 @@
|
|
|
135
140
|
background: #0F4862;
|
|
136
141
|
color: #ffffff;
|
|
137
142
|
border-bottom: none;
|
|
143
|
+
position: absolute;
|
|
144
|
+
width: 260px;
|
|
145
|
+
border-bottom-right-radius: 15px;
|
|
138
146
|
}
|
|
139
147
|
|
|
140
148
|
.studio-navbar .brand span,
|
|
@@ -161,7 +169,7 @@
|
|
|
161
169
|
.studio-panels {
|
|
162
170
|
display: flex;
|
|
163
171
|
width: 100%;
|
|
164
|
-
height: calc(100vh
|
|
172
|
+
height: calc(100vh);
|
|
165
173
|
overflow-x: hidden;
|
|
166
174
|
}
|
|
167
175
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>
|
|
7
|
+
<title>QALITA CLI - Dashboard</title>
|
|
8
8
|
<link rel="icon" href="/static/favicon.ico" />
|
|
9
9
|
<link rel="stylesheet" href="/static/styles.css" />
|
|
10
10
|
</head>
|
|
@@ -88,10 +88,10 @@
|
|
|
88
88
|
<h3>Documentation</h3>
|
|
89
89
|
</div>
|
|
90
90
|
</div>
|
|
91
|
-
<p>Learn how to use
|
|
91
|
+
<p>Learn how to use QALITA and its features.</p>
|
|
92
92
|
<div>
|
|
93
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;">
|
|
94
|
+
type="button" style="width:100%;padding:12px 16px;">QALITA Docs</button></a>
|
|
95
95
|
</div>
|
|
96
96
|
</div>
|
|
97
97
|
</div>
|
|
@@ -322,7 +322,7 @@
|
|
|
322
322
|
<div class="footer">
|
|
323
323
|
<div class="inner">
|
|
324
324
|
<div>
|
|
325
|
-
<span>© QALITA</span> —
|
|
325
|
+
<span>© QALITA</span> — QALITA CLI
|
|
326
326
|
</div>
|
|
327
327
|
<div>
|
|
328
328
|
<span id="cli_version"></span>
|
qalita/web/templates/navbar.html
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="brand">
|
|
3
3
|
<div class="left">
|
|
4
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="
|
|
5
|
+
<img src="/static/logo-no-slogan.png" alt="QALITA" />
|
|
6
6
|
<span>CLI</span>
|
|
7
7
|
</a>
|
|
8
8
|
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>
|
|
7
|
+
<title>QALITA CLI - Source added</title>
|
|
8
8
|
<link rel="icon" href="/static/favicon.ico" />
|
|
9
9
|
<link rel="stylesheet" href="/static/styles.css" />
|
|
10
10
|
</head>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
<div class="footer">
|
|
37
37
|
<div class="inner">
|
|
38
38
|
<div>
|
|
39
|
-
<span>© QALITA</span> —
|
|
39
|
+
<span>© QALITA</span> — QALITA CLI
|
|
40
40
|
</div>
|
|
41
41
|
<div>
|
|
42
42
|
<span id="cli_version"></span>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>
|
|
7
|
+
<title>QALITA CLI - {{ title }}</title>
|
|
8
8
|
<link rel="icon" href="/static/favicon.ico" />
|
|
9
9
|
<link rel="stylesheet" href="/static/styles.css" />
|
|
10
10
|
</head>
|
|
@@ -393,7 +393,7 @@
|
|
|
393
393
|
<div class="footer">
|
|
394
394
|
<div class="inner">
|
|
395
395
|
<div>
|
|
396
|
-
<span>© QALITA</span> —
|
|
396
|
+
<span>© QALITA</span> — QALITA CLI
|
|
397
397
|
</div>
|
|
398
398
|
<div>
|
|
399
399
|
<span id="cli_version"></span>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>
|
|
7
|
+
<title>QALITA CLI - Select source</title>
|
|
8
8
|
<link rel="icon" href="/static/favicon.ico" />
|
|
9
9
|
<link rel="stylesheet" href="/static/styles.css" />
|
|
10
10
|
</head>
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
</div>
|
|
101
101
|
{% endfor %}
|
|
102
102
|
<div class="actions" style="margin-top:16px;">
|
|
103
|
-
<a class="btn" href="mailto:contact@qalita.io?subject=Suggest%20a%20new%20source%20type&body=Hi%
|
|
103
|
+
<a class="btn" href="mailto:contact@qalita.io?subject=Suggest%20a%20new%20source%20type&body=Hi%20QALITA%20team%2C%0A%0AI%27d%20like%20to%20suggest%20support%20for%20this%20source%20type%3A%20%5Bplease%20describe%5D%0A%0AThanks!">Suggest a new source type</a>
|
|
104
104
|
<a class="btn secondary" href="/">Cancel</a>
|
|
105
105
|
</div>
|
|
106
106
|
</div>
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
<div class="footer">
|
|
109
109
|
<div class="inner">
|
|
110
110
|
<div>
|
|
111
|
-
<span>© QALITA</span> —
|
|
111
|
+
<span>© QALITA</span> — QALITA CLI
|
|
112
112
|
</div>
|
|
113
113
|
<div>
|
|
114
114
|
<span id="cli_version"></span>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<div id="backend_status_dot" title="Checking backend..."
|
|
3
3
|
style="position:absolute; top:10px; right:10px; width:10px; height:10px; border-radius:50%; background:#9ca3af; box-shadow:0 0 0 1px #e5e7eb;">
|
|
4
4
|
</div>
|
|
5
|
+
<div id="ctx_error" style="display:none; margin:0 0 8px 0; padding:8px 10px; border:1px solid #fecaca; background:#fef2f2; color:#b91c1c; border-radius:6px; font-size:12px;"></div>
|
|
5
6
|
<div class="right" style="display:flex;align-items:center;gap:8px;">
|
|
6
7
|
<p style="margin: 0px; min-width: 130px;">Platform Context</p>
|
|
7
8
|
<select id="ctx_select" class="studio-input" style="margin-top: 0px; cursor:pointer;"></select>
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
<div>
|
|
18
19
|
<div class="studio-setup-title">Setup platform</div>
|
|
19
20
|
<div class="studio-setup-text">
|
|
20
|
-
Your current context doesn't provide
|
|
21
|
+
Your current context doesn't provide QALITA platform credentials.<br><br>
|
|
21
22
|
To use contextual data quality metadata, configure your Platform endpoint and token.
|
|
22
23
|
</div>
|
|
23
24
|
<div class="studio-setup-actions">
|
|
@@ -34,6 +35,15 @@
|
|
|
34
35
|
</div>
|
|
35
36
|
<script>
|
|
36
37
|
(function () {
|
|
38
|
+
function setCtxError(msg) {
|
|
39
|
+
try {
|
|
40
|
+
var el = document.getElementById('ctx_error');
|
|
41
|
+
if (!el) return;
|
|
42
|
+
if (!msg) { el.style.display = 'none'; el.textContent = ''; return; }
|
|
43
|
+
el.textContent = String(msg);
|
|
44
|
+
el.style.display = 'block';
|
|
45
|
+
} catch (e) { /* noop */ }
|
|
46
|
+
}
|
|
37
47
|
function showSetupCardIfNeeded(status) {
|
|
38
48
|
try {
|
|
39
49
|
var card = document.getElementById('setup_platform_card');
|
|
@@ -60,9 +70,10 @@
|
|
|
60
70
|
var url = (j && j.url) ? String(j.url) : '';
|
|
61
71
|
var code = (j && j.status != null) ? String(j.status) : 'N/A';
|
|
62
72
|
if (dot) { dot.style.background = isOk ? '#10b981' : '#ef4444'; dot.title = (isOk ? 'Backend reachable: ' : 'Backend not reachable: ') + (url || '(unknown)') + ' (HTTP ' + code + ')'; }
|
|
73
|
+
setCtxError(isOk ? '' : ('Backend not reachable: ' + (url || '(unknown)') + ' (HTTP ' + code + ')'));
|
|
63
74
|
showSetupCardIfNeeded(j || {});
|
|
64
75
|
})
|
|
65
|
-
.catch(function () { if (dot) { dot.style.background = '#ef4444'; dot.title = 'Backend check failed'; } });
|
|
76
|
+
.catch(function () { if (dot) { dot.style.background = '#ef4444'; dot.title = 'Backend check failed'; } setCtxError('Backend check failed'); });
|
|
66
77
|
}
|
|
67
78
|
function renderIssues(items) {
|
|
68
79
|
var root = document.getElementById('issues_container');
|
|
@@ -213,6 +224,7 @@
|
|
|
213
224
|
.then(function (r) { return r.json(); })
|
|
214
225
|
.then(function (j) {
|
|
215
226
|
var items = (j && j.ok) ? (j.items || []) : [];
|
|
227
|
+
if (!j || !j.ok) { setCtxError((j && (j.message || j.error)) || 'Failed to load issues'); } else { setCtxError(''); }
|
|
216
228
|
if (!projectId) { renderIssues(items); return; }
|
|
217
229
|
// Client-side filter by project sources for robustness
|
|
218
230
|
var srcUrl = '/studio/sources?project_id=' + encodeURIComponent(projectId);
|
|
@@ -225,9 +237,9 @@
|
|
|
225
237
|
var filtered = items.filter(function (it) { var sid = extractIssueSourceId(it); return sid && set[sid]; });
|
|
226
238
|
renderIssues(filtered);
|
|
227
239
|
})
|
|
228
|
-
.catch(function () { renderIssues([]); });
|
|
240
|
+
.catch(function () { setCtxError('Failed to load project sources'); renderIssues([]); });
|
|
229
241
|
})
|
|
230
|
-
.catch(function () { renderIssues([]); });
|
|
242
|
+
.catch(function () { setCtxError('Failed to load issues'); renderIssues([]); });
|
|
231
243
|
}
|
|
232
244
|
function loadProjects() {
|
|
233
245
|
function normalizeProjects(j) {
|
|
@@ -251,9 +263,10 @@
|
|
|
251
263
|
.then(function (r) { return r.json(); })
|
|
252
264
|
.then(function (j) {
|
|
253
265
|
var items = normalizeProjects(j && (j.items != null ? j.items : j));
|
|
266
|
+
if (!j) { setCtxError('Failed to load projects'); } else { setCtxError(''); }
|
|
254
267
|
renderProjects(items);
|
|
255
268
|
})
|
|
256
|
-
.catch(function () { renderProjects([]); });
|
|
269
|
+
.catch(function () { setCtxError('Failed to load projects'); renderProjects([]); });
|
|
257
270
|
}
|
|
258
271
|
function loadContexts() {
|
|
259
272
|
fetch('/contexts').then(r => r.json()).then(j => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<title>
|
|
7
|
+
<title>QALITA Studio</title>
|
|
8
8
|
<link rel="icon" href="/static/studio.png" />
|
|
9
9
|
<link rel="stylesheet" href="/static/styles.css" />
|
|
10
10
|
<link rel="stylesheet" href="/static/studio.css" />
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
<body class="studio" style="background-repeat: no-repeat;">
|
|
14
14
|
{% include 'studio/navbar.html' %}
|
|
15
15
|
<div class="studio-panels" id="studio_panels">
|
|
16
|
-
<section class="panel" id="panel_context" style="flex: 0 0
|
|
16
|
+
<section class="panel" id="panel_context" style="flex: 0 0 18%; margin-top: 40px;">
|
|
17
17
|
{% include 'studio/context-panel.html' %}
|
|
18
18
|
</section>
|
|
19
19
|
<div class="resizer" data-resizer="left-center"></div>
|
|
20
|
-
<section class="panel" id="panel_view" style="flex: 0 0
|
|
20
|
+
<section class="panel" id="panel_view" style="flex: 0 0 49%;">
|
|
21
21
|
{% include 'studio/view-panel.html' %}
|
|
22
22
|
</section>
|
|
23
23
|
<div class="resizer" data-resizer="center-right"></div>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
function onMouseMove(e) {
|
|
51
51
|
if (!active) return;
|
|
52
52
|
const dx = e.clientX - startX;
|
|
53
|
-
const min =
|
|
53
|
+
const min = 263;
|
|
54
54
|
if (active.dataset.resizer === 'left-center') {
|
|
55
55
|
let w0 = Math.max(min, startWidths[0] + dx);
|
|
56
56
|
let w1 = Math.max(min, startWidths[1] - dx);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<div class="topbar studio-navbar">
|
|
2
|
-
<div class="brand" style="max-width:100%; padding:
|
|
2
|
+
<div class="brand" style="max-width:100%; padding: 6px 23px;">
|
|
3
3
|
<div class="left">
|
|
4
4
|
<a href="/" style="display:flex;align-items:flex-end;gap:5px;text-decoration:none;color:inherit;">
|
|
5
|
-
<img src="/static/logo-white-no-slogan.svg" alt="Logo
|
|
5
|
+
<img src="/static/logo-white-no-slogan.svg" alt="Logo QALITA" width="25" height="25"
|
|
6
6
|
style="height:25px;" />
|
|
7
7
|
<span style="font-size: 20px; font-weight: 300; color: #ffffff;">Studio</span>
|
|
8
8
|
<span class="badge"
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
<p>Here will be displayed contextualized data.</p>
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
|
+
<div id="vp_error" style="display:none; margin:8px 0; padding:8px 10px; border:1px solid #fecaca; background:#fef2f2; color:#b91c1c; border-radius:6px; font-size:12px;"></div>
|
|
12
|
+
|
|
11
13
|
<div id="vp_image" style="display:none; height:100%; overflow:auto;">
|
|
12
14
|
<img id="vp_image_img" alt="image" style="max-width:100%; height:auto; display:block; margin: 0 auto;" />
|
|
13
15
|
</div>
|
|
@@ -57,6 +59,66 @@
|
|
|
57
59
|
var vpTableTbl = document.getElementById('vp_table_tbl');
|
|
58
60
|
var vpSources = document.getElementById('vp_sources');
|
|
59
61
|
var vpSourcesContainer = document.getElementById('vp_sources_container');
|
|
62
|
+
// Table incremental rendering state
|
|
63
|
+
var tableState = { headers: [], rows: [], rendered: 0, pageSize: 200, isLoading: false, endReached: false };
|
|
64
|
+
var tableScrollHandler = null;
|
|
65
|
+
|
|
66
|
+
// --- Icons helpers (use public/sources-logos files) ---
|
|
67
|
+
function getIconSrcForType(type) {
|
|
68
|
+
var t = String(type || '').toLowerCase();
|
|
69
|
+
function src(name) { return '/static/sources-logos/' + name; }
|
|
70
|
+
if (!t) return src('database.svg');
|
|
71
|
+
if (t.indexOf('folder') !== -1) return src('folder.svg');
|
|
72
|
+
if (t === 'file') return src('file.svg');
|
|
73
|
+
if (t.indexOf('image') !== -1 || t.indexOf('png') !== -1 || t.indexOf('jpg') !== -1 || t.indexOf('jpeg') !== -1) return src('picture.png');
|
|
74
|
+
if (t.indexOf('csv') !== -1) return src('csv.svg');
|
|
75
|
+
if (t.indexOf('xlsx') !== -1) return src('xlsx.svg');
|
|
76
|
+
if (t.indexOf('xls') !== -1) return src('xls.svg');
|
|
77
|
+
if (t.indexOf('excel') !== -1) return src('excel.svg');
|
|
78
|
+
if (t.indexOf('json') !== -1) return src('json.png');
|
|
79
|
+
if (t.indexOf('parquet') !== -1) return src('parquet.svg');
|
|
80
|
+
if (t.indexOf('avro') !== -1) return src('avro.svg');
|
|
81
|
+
if (t.indexOf('s3') !== -1) return src('s3.svg');
|
|
82
|
+
if (t.indexOf('gcs') !== -1) return src('gcs.png');
|
|
83
|
+
if (t.indexOf('azure_blob') !== -1 || t.indexOf('azure-blob') !== -1) return src('azure_blob.svg');
|
|
84
|
+
if (t.indexOf('hdfs') !== -1) return src('hdfs.svg');
|
|
85
|
+
if (t.indexOf('postgres') !== -1) return src('postgresql.svg');
|
|
86
|
+
if (t.indexOf('mysql') !== -1) return src('mysql.svg');
|
|
87
|
+
if (t.indexOf('mssql') !== -1 || t.indexOf('sqlserver') !== -1) return src('mssql.svg');
|
|
88
|
+
if (t.indexOf('sqlite') !== -1) return src('sqlite.svg');
|
|
89
|
+
if (t.indexOf('oracle') !== -1) return src('oracle.svg');
|
|
90
|
+
if (t.indexOf('redshift') !== -1) return src('redshift.png');
|
|
91
|
+
if (t.indexOf('snowflake') !== -1) return src('snowflake.png');
|
|
92
|
+
if (t.indexOf('clickhouse') !== -1) return src('clickhouse.png');
|
|
93
|
+
if (t.indexOf('duckdb') !== -1) return src('duckdb.png');
|
|
94
|
+
if (t.indexOf('databricks') !== -1) return src('databricks.png');
|
|
95
|
+
if (t.indexOf('cassandra') !== -1) return src('cassandra.svg');
|
|
96
|
+
if (t.indexOf('elasticsearch') !== -1) return src('elasticsearch.svg');
|
|
97
|
+
if (t.indexOf('mongodb') !== -1) return src('mongodb.svg');
|
|
98
|
+
if (t.indexOf('cockroach') !== -1) return src('cockroach-db.png');
|
|
99
|
+
if (t.indexOf('yugabyte') !== -1) return src('yugabyte-db.png');
|
|
100
|
+
if (t.indexOf('questdb') !== -1) return src('questdb.png');
|
|
101
|
+
if (t.indexOf('timescale') !== -1) return src('timescale.png');
|
|
102
|
+
if (t.indexOf('alloy') !== -1) return src('alloy-db.png');
|
|
103
|
+
if (t.indexOf('cloud sql') !== -1 || t.indexOf('cloud-sql') !== -1) return src('cloud-sql.png');
|
|
104
|
+
if (t.indexOf('athena') !== -1) return src('amazon-athena.png');
|
|
105
|
+
if (t.indexOf('rds') !== -1) return src('amazon-rds.png');
|
|
106
|
+
if (t.indexOf('bigquery') !== -1) return src('bigquery.png');
|
|
107
|
+
if (t.indexOf('synapse') !== -1) return src('azure-synapse-analytics.png');
|
|
108
|
+
if (t.indexOf('single') !== -1 && t.indexOf('store') !== -1) return src('single-store.png');
|
|
109
|
+
if (t.indexOf('starburst') !== -1) return src('starburst.png');
|
|
110
|
+
if (t.indexOf('teradata') !== -1) return src('teradata.png');
|
|
111
|
+
if (t.indexOf('hana') !== -1 || t.indexOf('sap') !== -1) return src('sap-hana.png');
|
|
112
|
+
if (t.indexOf('sftp') !== -1) return src('sftp.png');
|
|
113
|
+
if (t.indexOf('stream') !== -1) return src('stream.png');
|
|
114
|
+
if (t.indexOf('api') !== -1) return src('api.svg');
|
|
115
|
+
return src('database.svg');
|
|
116
|
+
}
|
|
117
|
+
function iconHtmlForType(type) {
|
|
118
|
+
var src = getIconSrcForType(type);
|
|
119
|
+
var title = String(type || '').toUpperCase();
|
|
120
|
+
return '<img src="' + src + '" alt="' + title.replace(/"/g, '') + '" title="' + title.replace(/"/g, '') + '" style="width:16px;height:16px;object-fit:contain;margin-right:6px;vertical-align:middle;" />';
|
|
121
|
+
}
|
|
60
122
|
|
|
61
123
|
function hideAll() {
|
|
62
124
|
[vpImage, vpPdf, vpText, vpJson, vpTable].forEach(function (el) { if (el) el.style.display = 'none'; });
|
|
@@ -80,8 +142,27 @@
|
|
|
80
142
|
return { headers: headers, rows: body };
|
|
81
143
|
}
|
|
82
144
|
|
|
83
|
-
function
|
|
84
|
-
|
|
145
|
+
function appendTableRows(count) {
|
|
146
|
+
var tbody = vpTableTbl.querySelector('tbody');
|
|
147
|
+
var start = tableState.rendered;
|
|
148
|
+
var end = Math.min(start + (count != null ? count : tableState.pageSize), tableState.rows.length);
|
|
149
|
+
for (var i = start; i < end; i++) {
|
|
150
|
+
var r = tableState.rows[i];
|
|
151
|
+
var tr = document.createElement('tr');
|
|
152
|
+
r.forEach(function (c) {
|
|
153
|
+
var td = document.createElement('td');
|
|
154
|
+
td.textContent = c == null ? '' : String(c);
|
|
155
|
+
td.style.borderBottom = '1px solid #f3f4f6';
|
|
156
|
+
td.style.padding = '6px 8px';
|
|
157
|
+
tr.appendChild(td);
|
|
158
|
+
});
|
|
159
|
+
tbody.appendChild(tr);
|
|
160
|
+
}
|
|
161
|
+
tableState.rendered = end;
|
|
162
|
+
if (end >= tableState.rows.length) { tableState.endReached = true; }
|
|
163
|
+
}
|
|
164
|
+
function setupTableIncrementalRendering(data) {
|
|
165
|
+
// Normalize data to headers/rows
|
|
85
166
|
var headers = [];
|
|
86
167
|
var rows = [];
|
|
87
168
|
if (data && Array.isArray(data.headers) && Array.isArray(data.rows)) {
|
|
@@ -93,13 +174,19 @@
|
|
|
93
174
|
var parsed = toRowsFromCsv(data.csv);
|
|
94
175
|
headers = parsed.headers; rows = parsed.rows;
|
|
95
176
|
}
|
|
177
|
+
// Reset state
|
|
178
|
+
tableState.headers = headers || [];
|
|
179
|
+
tableState.rows = Array.isArray(rows) ? rows : [];
|
|
180
|
+
tableState.rendered = 0;
|
|
181
|
+
tableState.endReached = false;
|
|
182
|
+
// Build header
|
|
96
183
|
var thead = vpTableTbl.querySelector('thead');
|
|
97
184
|
var tbody = vpTableTbl.querySelector('tbody');
|
|
98
185
|
thead.innerHTML = '';
|
|
99
186
|
tbody.innerHTML = '';
|
|
100
|
-
if (headers
|
|
187
|
+
if (tableState.headers.length) {
|
|
101
188
|
var trh = document.createElement('tr');
|
|
102
|
-
headers.forEach(function (h) {
|
|
189
|
+
tableState.headers.forEach(function (h) {
|
|
103
190
|
var th = document.createElement('th');
|
|
104
191
|
th.textContent = String(h);
|
|
105
192
|
th.style.textAlign = 'left';
|
|
@@ -112,20 +199,25 @@
|
|
|
112
199
|
});
|
|
113
200
|
thead.appendChild(trh);
|
|
114
201
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
202
|
+
// Initial 200-row preview
|
|
203
|
+
appendTableRows(tableState.pageSize);
|
|
204
|
+
// Attach scroll listener for infinite scroll
|
|
205
|
+
if (tableScrollHandler && vpTable) { try { vpTable.removeEventListener('scroll', tableScrollHandler); } catch (e) { } }
|
|
206
|
+
tableScrollHandler = function () {
|
|
207
|
+
if (!vpTable || tableState.endReached || tableState.isLoading) return;
|
|
208
|
+
var remaining = (vpTable.scrollHeight - vpTable.scrollTop - vpTable.clientHeight);
|
|
209
|
+
if (remaining < 200) {
|
|
210
|
+
tableState.isLoading = true;
|
|
211
|
+
// Lazy append next chunk after a frame to keep UI responsive
|
|
212
|
+
requestAnimationFrame(function () {
|
|
213
|
+
appendTableRows(tableState.pageSize);
|
|
214
|
+
tableState.isLoading = false;
|
|
124
215
|
});
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
if (vpTable) vpTable.addEventListener('scroll', tableScrollHandler);
|
|
128
219
|
}
|
|
220
|
+
function renderTable(data) { setupTableIncrementalRendering(data); }
|
|
129
221
|
|
|
130
222
|
function pretty(obj) {
|
|
131
223
|
try { return JSON.stringify(obj, null, 2); } catch (e) { return String(obj); }
|
|
@@ -186,6 +278,12 @@
|
|
|
186
278
|
function writeViewLabels(map) {
|
|
187
279
|
try { sessionStorage.setItem('studio_view_labels', JSON.stringify(map || {})); } catch (e) { }
|
|
188
280
|
}
|
|
281
|
+
function readViewTypes() {
|
|
282
|
+
try { return JSON.parse(sessionStorage.getItem('studio_view_types') || '{}'); } catch (e) { return {}; }
|
|
283
|
+
}
|
|
284
|
+
function writeViewTypes(map) {
|
|
285
|
+
try { sessionStorage.setItem('studio_view_types', JSON.stringify(map || {})); } catch (e) { }
|
|
286
|
+
}
|
|
189
287
|
function currentSourceId() { try { return new URLSearchParams(window.location.search).get('source_id') || ''; } catch (e) { return ''; } }
|
|
190
288
|
function ensureViewTab(id) {
|
|
191
289
|
if (!id) return;
|
|
@@ -229,6 +327,7 @@
|
|
|
229
327
|
var tabs = readViewTabs();
|
|
230
328
|
var selectedId = currentSourceId();
|
|
231
329
|
var labels = readViewLabels();
|
|
330
|
+
var types = readViewTypes();
|
|
232
331
|
function removeViewTab(id) {
|
|
233
332
|
var list = readViewTabs().filter(function (t) { return t !== id; });
|
|
234
333
|
writeViewTabs(list);
|
|
@@ -256,7 +355,9 @@
|
|
|
256
355
|
container.style.cssText = 'display:inline-flex; align-items:center; gap:4px; border:1px solid #e5e7eb; background:' + (id === selectedId ? '#eef2ff' : '#ffffff') + '; color:#111827; padding:2px 4px; border-radius:6px; white-space:nowrap;';
|
|
257
356
|
var labelBtn = document.createElement('button');
|
|
258
357
|
var label = (labels && labels[id]) ? String(labels[id]) : ('Source ' + id);
|
|
259
|
-
|
|
358
|
+
var typeForId = (types && types[id]) ? String(types[id]) : '';
|
|
359
|
+
var icon = iconHtmlForType(typeForId);
|
|
360
|
+
labelBtn.innerHTML = icon + '<span>' + label.replace(/</g, '<') + '</span>';
|
|
260
361
|
labelBtn.title = label;
|
|
261
362
|
labelBtn.style.cssText = 'background:transparent; border:0; color:inherit; padding:2px 4px; cursor:pointer;';
|
|
262
363
|
labelBtn.addEventListener('click', function () {
|
|
@@ -283,8 +384,9 @@
|
|
|
283
384
|
function showError(message) {
|
|
284
385
|
try {
|
|
285
386
|
hideAll();
|
|
286
|
-
|
|
287
|
-
if (
|
|
387
|
+
var err = document.getElementById('vp_error');
|
|
388
|
+
if (err) { err.textContent = String(message || 'Error'); err.style.display = 'block'; }
|
|
389
|
+
if (vpText) vpText.style.display = 'none';
|
|
288
390
|
} catch (e) { /* noop */ }
|
|
289
391
|
}
|
|
290
392
|
async function loadFromUrl() {
|
|
@@ -293,12 +395,13 @@
|
|
|
293
395
|
try { if (vpSources) vpSources.style.display = srcId ? 'none' : 'block'; } catch (e) { }
|
|
294
396
|
if (!srcId) { try { hideAll(); } catch (e) { } return; }
|
|
295
397
|
try {
|
|
296
|
-
|
|
297
|
-
var url = '/sources/preview?source_id=' + encodeURIComponent(srcId) +
|
|
398
|
+
// Always fetch full preview; render 200 rows first, then lazy-load more client-side
|
|
399
|
+
var url = '/sources/preview?source_id=' + encodeURIComponent(srcId) + '&verbose=1';
|
|
298
400
|
console.log('[ViewPanel] fetching preview:', url);
|
|
299
401
|
var r = await fetch(url);
|
|
300
402
|
var j = await r.json();
|
|
301
403
|
if (j && j.ok && j.view) {
|
|
404
|
+
var err = document.getElementById('vp_error'); if (err) { err.style.display = 'none'; err.textContent = ''; }
|
|
302
405
|
if (j.debug) console.log('[ViewPanel] debug:', j.debug);
|
|
303
406
|
setView(j.view);
|
|
304
407
|
ensureViewTab(srcId);
|
|
@@ -362,7 +465,8 @@
|
|
|
362
465
|
card.style.opacity = '0.5';
|
|
363
466
|
card.style.filter = 'grayscale(100%)';
|
|
364
467
|
}
|
|
365
|
-
|
|
468
|
+
var icon = iconHtmlForType(type);
|
|
469
|
+
card.innerHTML = '<div style="font-weight:600; color:#111827; display:flex; align-items:center; gap:6px;">' + icon + '<span>' + name.replace(/</g, '<') + '</span></div>' +
|
|
366
470
|
'<div class="muted" style="font-size:12px;">' + (type ? ('Type: ' + type) : '') + '</div>' +
|
|
367
471
|
'<div class="muted" style="font-size:12px;">#' + id + '</div>';
|
|
368
472
|
if (selectedId && id === selectedId) {
|
|
@@ -400,12 +504,16 @@
|
|
|
400
504
|
// Build and cache labels map for view tabs
|
|
401
505
|
try {
|
|
402
506
|
var labelsMap = readViewLabels();
|
|
507
|
+
var typesMap = readViewTypes();
|
|
403
508
|
items.forEach(function (it) {
|
|
404
509
|
var id = String(it.id || it.source_id || '');
|
|
405
510
|
var name = it.name || (it.source && it.source.name) || ('Source ' + id);
|
|
511
|
+
var type = it.type || (it.source && it.source.type) || '';
|
|
406
512
|
if (id) labelsMap[id] = String(name);
|
|
513
|
+
if (id) typesMap[id] = String(type);
|
|
407
514
|
});
|
|
408
515
|
writeViewLabels(labelsMap);
|
|
516
|
+
writeViewTypes(typesMap);
|
|
409
517
|
// Re-render tabs to reflect labels instead of IDs
|
|
410
518
|
try { renderViewTabs(); } catch (e) { }
|
|
411
519
|
} catch (e) { }
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: qalita
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: QALITA Platform Command Line Interface
|
|
5
|
+
License-File: LICENSE
|
|
5
6
|
Author: QALITA SAS
|
|
6
7
|
Author-email: contact@qalita.io
|
|
7
8
|
Requires-Python: >=3.10,<4.0
|
|
@@ -17,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
17
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
22
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
21
23
|
Requires-Dist: azure-storage-blob (>=12.19.1,<13.0.0)
|
|
22
24
|
Requires-Dist: boto3 (>=1.34.81,<2.0.0)
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
qalita/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
qalita/__main__.py,sha256=
|
|
2
|
+
qalita/__main__.py,sha256=mUdL2kKMsr47UP2GIJwBNcDR4yZv-ApcSH-tfcRL03g,2518
|
|
3
3
|
qalita/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
qalita/commands/agent.py,sha256=
|
|
5
|
-
qalita/commands/pack.py,sha256=
|
|
6
|
-
qalita/commands/source.py,sha256=
|
|
4
|
+
qalita/commands/agent.py,sha256=HhgJA3ni6D49xxMMoCJthLYFVR5yYCPEr8GI41Vvfnw,47113
|
|
5
|
+
qalita/commands/pack.py,sha256=xnH-uAnaqMnyVnO7KZ2DNqmd9AgF_j5AgjDE1OnG6d0,39029
|
|
6
|
+
qalita/commands/source.py,sha256=ObRD2CcDynGbMrmj__FhWvPvR0H6HEn5QSLNR8awQUQ,30945
|
|
7
7
|
qalita/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
qalita/internal/config.py,sha256=P9UU3BH-CIH68-qZjmnk8juzZZ5HJ701hrY6EvrPFOA,4081
|
|
9
9
|
qalita/internal/error_patterns.py,sha256=QDFNZEoTmqVOHkiGFljstY6VOhux7d4p8FIL3pKzwtQ,1447
|
|
10
10
|
qalita/internal/logger.py,sha256=4xWy2BZII89nUw4tKrLXFPOlVGONm8KUBgzX2XZ3u7g,1868
|
|
11
11
|
qalita/internal/request.py,sha256=s-rE9kKRhV9IEveclB2YjAY8FRevKb6qjblM8-PbV20,6209
|
|
12
|
-
qalita/internal/utils.py,sha256=
|
|
12
|
+
qalita/internal/utils.py,sha256=5Q9P4skA6KKkd4OvIrVH6VPniNud05L-Zr0zt395Nc4,5746
|
|
13
13
|
qalita/web/__init__.py,sha256=NRcQjZSizkqN0a-LutsN7X9LBQ8MhyazXBSuqzUEmXE,62
|
|
14
|
-
qalita/web/app.py,sha256=
|
|
15
|
-
qalita/web/blueprints/agents.py,sha256=
|
|
14
|
+
qalita/web/app.py,sha256=92M2K7vxDIYaI81D-zvdj4VfCsaTTDs6KJZu6dy5s6U,1323
|
|
15
|
+
qalita/web/blueprints/agents.py,sha256=q_SqdSzzHMsstSzEjHGtq75jFt3wQ6p3atjOSzKgiUw,17367
|
|
16
16
|
qalita/web/blueprints/context.py,sha256=wIcfBtu3l9qwMe5IPa0VQShELsY3ENPt4Q9OO3L8EsE,6451
|
|
17
17
|
qalita/web/blueprints/dashboard.py,sha256=R_1_oAM-Ol0kx5GZkKTaB8c5vjdz-iIK-SGu2RIHE_w,7454
|
|
18
18
|
qalita/web/blueprints/helpers.py,sha256=Hnulyrd-YrHoz2LtGCKCq9MgUeoNoNECTyGDap2DFYI,12724
|
|
@@ -81,21 +81,21 @@ qalita/web/public/sources-logos/xls.svg,sha256=ckgO7s5pv9numYYFJboxvGQ_P3fLA1zz-
|
|
|
81
81
|
qalita/web/public/sources-logos/xlsx.svg,sha256=ckgO7s5pv9numYYFJboxvGQ_P3fLA1zz-2xiERcz2bE,2044
|
|
82
82
|
qalita/web/public/sources-logos/yugabyte-db.png,sha256=-sGA5gqwSIHlGqk6LHNQ5EogsywwKXiWbKXS3PluYKI,5212
|
|
83
83
|
qalita/web/public/studio-logo.svg,sha256=NCFJM0rw6XxKcjCJ7bzih1aGudHAjYB1bWUXcF9W19U,620463
|
|
84
|
-
qalita/web/public/studio.css,sha256=
|
|
84
|
+
qalita/web/public/studio.css,sha256=bHWyfPUbtYU8jDUKepNY6K0Am4qeG7ewQ_nnKnh4M6M,5060
|
|
85
85
|
qalita/web/public/studio.png,sha256=9kLYN5c8nqK7TKT8UHjfPSKBI60zDFsIcYFbWw3cVfY,461702
|
|
86
86
|
qalita/web/public/styles.css,sha256=xmy_c0fmUKBEgPF2L_qrQ2eC1erw-zcAndpMQMjHJbM,10486
|
|
87
|
-
qalita/web/templates/dashboard.html,sha256=
|
|
88
|
-
qalita/web/templates/navbar.html,sha256=
|
|
89
|
-
qalita/web/templates/sources/added.html,sha256=
|
|
90
|
-
qalita/web/templates/sources/edit.html,sha256=
|
|
91
|
-
qalita/web/templates/sources/select-source.html,sha256=
|
|
87
|
+
qalita/web/templates/dashboard.html,sha256=pAuWMRaSjInqNitecf4mkI2eX-UeqpC37Jbc_tGCeuk,17045
|
|
88
|
+
qalita/web/templates/navbar.html,sha256=W0eBuH_vrs4GyxkSzxsppOchkgtvnKM-uc07mP5mkdA,1916
|
|
89
|
+
qalita/web/templates/sources/added.html,sha256=uTu5jofRi9t9pvWRnc9AtD9B396DvnqDo6HoajVU3DA,1938
|
|
90
|
+
qalita/web/templates/sources/edit.html,sha256=DM5i3Y__MMG0PzJm--OXQSo5PbI4fcRo4UYHm2qGMxA,19723
|
|
91
|
+
qalita/web/templates/sources/select-source.html,sha256=dBTEpCu8KTjmiOG_gBIUFEdGAnGmnV8EFQid7chsVA0,6179
|
|
92
92
|
qalita/web/templates/studio/agent-panel.html,sha256=cc_zcUgkQHwxBz2_Nkvw3BCO3L_zhQDcrnp0woMwI_A,38790
|
|
93
|
-
qalita/web/templates/studio/context-panel.html,sha256=
|
|
94
|
-
qalita/web/templates/studio/index.html,sha256=
|
|
95
|
-
qalita/web/templates/studio/navbar.html,sha256=
|
|
96
|
-
qalita/web/templates/studio/view-panel.html,sha256=
|
|
97
|
-
qalita-2.
|
|
98
|
-
qalita-2.
|
|
99
|
-
qalita-2.
|
|
100
|
-
qalita-2.
|
|
101
|
-
qalita-2.
|
|
93
|
+
qalita/web/templates/studio/context-panel.html,sha256=M8yfYcJQ_2WSwnOLlCTQETzctzL-rjlKLF7PlAUV0PU,15312
|
|
94
|
+
qalita/web/templates/studio/index.html,sha256=NI7zF-4cHQ3id-a_R3GNQ8gQ2Bw4A6liyEZ53AO0QOU,2823
|
|
95
|
+
qalita/web/templates/studio/navbar.html,sha256=IQZ7TFOXv3r5yZmP9f1v7BMUCQU8mOajMV82UPeY3cg,746
|
|
96
|
+
qalita/web/templates/studio/view-panel.html,sha256=JREfFIabpuAZctAzbE_mT_ZDk65MBWevjRNxQUrO8Pw,25198
|
|
97
|
+
qalita-2.3.0.dist-info/METADATA,sha256=KFd1LHzaTXeRvTkC2GgwBUvn8ZWfkaXyJMQtwl_hbrE,2412
|
|
98
|
+
qalita-2.3.0.dist-info/WHEEL,sha256=M5asmiAlL6HEcOq52Yi5mmk9KmTVjY2RDPtO4p9DMrc,88
|
|
99
|
+
qalita-2.3.0.dist-info/entry_points.txt,sha256=RxEByZDKtsRrsDauuINx9XMVP6k26B_CglUmtH206Qo,47
|
|
100
|
+
qalita-2.3.0.dist-info/licenses/LICENSE,sha256=cZt92dnxw87-VK4HB6KnmYV7mpf4JUdBkAHzFn1kQxM,22458
|
|
101
|
+
qalita-2.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|