meerschaum 3.0.0rc2__py3-none-any.whl → 3.0.0rc4__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.
- meerschaum/_internal/shell/Shell.py +5 -4
- meerschaum/actions/bootstrap.py +1 -1
- meerschaum/actions/edit.py +6 -3
- meerschaum/actions/start.py +1 -1
- meerschaum/api/_events.py +5 -0
- meerschaum/api/dash/callbacks/__init__.py +1 -0
- meerschaum/api/dash/callbacks/dashboard.py +93 -115
- meerschaum/api/dash/callbacks/jobs.py +11 -5
- meerschaum/api/dash/callbacks/pipes.py +194 -14
- meerschaum/api/dash/callbacks/settings/__init__.py +0 -1
- meerschaum/api/dash/callbacks/{settings/tokens.py → tokens.py} +3 -2
- meerschaum/api/dash/components.py +6 -7
- meerschaum/api/dash/jobs.py +1 -1
- meerschaum/api/dash/keys.py +17 -1
- meerschaum/api/dash/pages/__init__.py +2 -1
- meerschaum/api/dash/pages/{job.py → jobs.py} +10 -7
- meerschaum/api/dash/pages/pipes.py +16 -5
- meerschaum/api/dash/pages/settings/__init__.py +0 -1
- meerschaum/api/dash/pages/{settings/tokens.py → tokens.py} +6 -8
- meerschaum/api/dash/pipes.py +219 -3
- meerschaum/api/dash/tokens.py +27 -30
- meerschaum/config/_default.py +5 -4
- meerschaum/config/_paths.py +1 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/connectors/instance/_tokens.py +6 -2
- meerschaum/connectors/sql/_SQLConnector.py +14 -0
- meerschaum/connectors/sql/_pipes.py +63 -23
- meerschaum/connectors/sql/tables/__init__.py +254 -122
- meerschaum/core/Pipe/__init__.py +17 -1
- meerschaum/core/Pipe/_attributes.py +5 -2
- meerschaum/core/Token/_Token.py +1 -1
- meerschaum/plugins/bootstrap.py +508 -3
- meerschaum/utils/_get_pipes.py +31 -5
- meerschaum/utils/dataframe.py +8 -2
- meerschaum/utils/dtypes/__init__.py +2 -3
- meerschaum/utils/dtypes/sql.py +11 -11
- meerschaum/utils/formatting/_pprint.py +1 -0
- meerschaum/utils/pipes.py +6 -2
- meerschaum/utils/sql.py +1 -1
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/METADATA +1 -1
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/RECORD +47 -47
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/WHEEL +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/entry_points.txt +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/licenses/NOTICE +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/top_level.txt +0 -0
- {meerschaum-3.0.0rc2.dist-info → meerschaum-3.0.0rc4.dist-info}/zip-safe +0 -0
@@ -781,10 +781,11 @@ class Shell(cmd.Cmd):
|
|
781
781
|
instance_keys += ':main'
|
782
782
|
|
783
783
|
conn_attrs = parse_instance_keys(instance_keys, construct=False, debug=debug)
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
784
|
+
conn_keys = (
|
785
|
+
str(get_connector(debug=debug))
|
786
|
+
if conn_attrs is None
|
787
|
+
else instance_keys
|
788
|
+
)
|
788
789
|
|
789
790
|
shell_attrs['instance_keys'] = conn_keys
|
790
791
|
|
meerschaum/actions/bootstrap.py
CHANGED
@@ -429,7 +429,7 @@ def _bootstrap_plugins(
|
|
429
429
|
action = [prompt("Enter the name of your new plugin:")]
|
430
430
|
|
431
431
|
for plugin_name in action:
|
432
|
-
bootstrap_success, bootstrap_msg = bootstrap_plugin(plugin_name)
|
432
|
+
bootstrap_success, bootstrap_msg = bootstrap_plugin(plugin_name, debug=debug)
|
433
433
|
if not bootstrap_success:
|
434
434
|
return bootstrap_success, bootstrap_msg
|
435
435
|
|
meerschaum/actions/edit.py
CHANGED
@@ -552,7 +552,12 @@ def _edit_tokens(
|
|
552
552
|
dateutil_parser = mrsm.attempt_import('dateutil.parser')
|
553
553
|
|
554
554
|
if not action:
|
555
|
-
return
|
555
|
+
return (
|
556
|
+
False, (
|
557
|
+
"Provide token labels or IDs for the tokens to edit\n"
|
558
|
+
" (run `show tokens` to see registered tokens)."
|
559
|
+
)
|
560
|
+
)
|
556
561
|
|
557
562
|
conn = parse_instance_keys(mrsm_instance)
|
558
563
|
|
@@ -628,8 +633,6 @@ def _edit_tokens(
|
|
628
633
|
|
629
634
|
return True, msg
|
630
635
|
|
631
|
-
|
632
|
-
|
633
636
|
|
634
637
|
### NOTE: This must be the final statement of the module.
|
635
638
|
### Any subactions added below these lines will not
|
meerschaum/actions/start.py
CHANGED
meerschaum/api/_events.py
CHANGED
@@ -98,6 +98,11 @@ async def startup():
|
|
98
98
|
await shutdown()
|
99
99
|
os._exit(1)
|
100
100
|
|
101
|
+
conn = get_api_connector()
|
102
|
+
if conn.type == 'sql':
|
103
|
+
from meerschaum.connectors.sql.tables import get_tables
|
104
|
+
_ = get_tables(conn, refresh=True, create=True, debug=debug)
|
105
|
+
|
101
106
|
start_check_jobs_thread()
|
102
107
|
|
103
108
|
|
@@ -10,6 +10,7 @@ from meerschaum.api import debug as _debug
|
|
10
10
|
import meerschaum.api.dash.callbacks.dashboard
|
11
11
|
import meerschaum.api.dash.callbacks.login
|
12
12
|
import meerschaum.api.dash.callbacks.plugins
|
13
|
+
import meerschaum.api.dash.callbacks.tokens
|
13
14
|
import meerschaum.api.dash.callbacks.jobs
|
14
15
|
import meerschaum.api.dash.callbacks.register
|
15
16
|
import meerschaum.api.dash.callbacks.pipes
|
@@ -72,8 +72,6 @@ keys_state = (
|
|
72
72
|
State({'type': 'input-flags-dropdown', 'index': ALL}, 'value'),
|
73
73
|
State({'type': 'input-flags-dropdown-text', 'index': ALL}, 'value'),
|
74
74
|
State('instance-select', 'value'),
|
75
|
-
State('content-div-right', 'children'),
|
76
|
-
State('success-alert-div', 'children'),
|
77
75
|
State('session-store', 'data'),
|
78
76
|
)
|
79
77
|
|
@@ -103,15 +101,20 @@ omit_actions = {
|
|
103
101
|
_paths = {
|
104
102
|
'login' : pages.login.layout,
|
105
103
|
'' : pages.dashboard.layout,
|
104
|
+
'pipes' : pages.pipes.layout,
|
106
105
|
'plugins' : pages.plugins.layout,
|
106
|
+
'tokens' : pages.tokens.layout,
|
107
107
|
'register': pages.register.layout,
|
108
108
|
'pipes' : pages.pipes.layout,
|
109
|
-
'
|
109
|
+
'jobs' : pages.jobs.layout,
|
110
110
|
}
|
111
|
-
_required_login = {''}
|
111
|
+
_required_login = {'', 'tokens', 'jobs', 'pipes'}
|
112
112
|
_pages = {
|
113
113
|
'Web Console': '/dash/',
|
114
|
+
'Pipes': '/dash/pipes',
|
114
115
|
'Plugins': '/dash/plugins',
|
116
|
+
'Tokens': '/dash/tokens',
|
117
|
+
'Jobs': '/dash/jobs',
|
115
118
|
}
|
116
119
|
|
117
120
|
|
@@ -495,17 +498,9 @@ def update_flags(input_flags_dropdown_values, n_clicks, input_flags_texts):
|
|
495
498
|
|
496
499
|
@dash_app.callback(
|
497
500
|
Output('connector-keys-dropdown', 'options'),
|
498
|
-
Output('connector-keys-list', 'children'),
|
499
|
-
Output('connector-keys-dropdown', 'value'),
|
500
501
|
Output('metric-keys-dropdown', 'options'),
|
501
|
-
Output('metric-keys-list', 'children'),
|
502
|
-
Output('metric-keys-dropdown', 'value'),
|
503
502
|
Output('location-keys-dropdown', 'options'),
|
504
|
-
Output('location-keys-list', 'children'),
|
505
|
-
Output('location-keys-dropdown', 'value'),
|
506
503
|
Output('tags-dropdown', 'options'),
|
507
|
-
Output('tags-list', 'children'),
|
508
|
-
Output('tags-dropdown', 'value'),
|
509
504
|
Output('instance-select', 'value'),
|
510
505
|
Output('instance-alert-div', 'children'),
|
511
506
|
Input('connector-keys-dropdown', 'value'),
|
@@ -547,15 +542,6 @@ def update_keys_options(
|
|
547
542
|
except Exception as e:
|
548
543
|
instance_alerts += [alert_from_success_tuple((False, str(e)))]
|
549
544
|
|
550
|
-
### Update the keys filters.
|
551
|
-
if connector_keys is None:
|
552
|
-
connector_keys = []
|
553
|
-
if metric_keys is None:
|
554
|
-
metric_keys = []
|
555
|
-
if location_keys is None:
|
556
|
-
location_keys = []
|
557
|
-
if tags is None:
|
558
|
-
tags = []
|
559
545
|
num_filter = 0
|
560
546
|
if connector_keys:
|
561
547
|
num_filter += 1
|
@@ -566,10 +552,6 @@ def update_keys_options(
|
|
566
552
|
if tags:
|
567
553
|
num_filter += 1
|
568
554
|
|
569
|
-
_ck_filter = connector_keys
|
570
|
-
_mk_filter = metric_keys
|
571
|
-
_lk_filter = location_keys
|
572
|
-
_tags_filter = tags
|
573
555
|
_ck_alone = (connector_keys and num_filter == 1) or instance_click
|
574
556
|
_mk_alone = (metric_keys and num_filter == 1) or instance_click
|
575
557
|
_lk_alone = (location_keys and num_filter == 1) or instance_click
|
@@ -582,109 +564,95 @@ def update_keys_options(
|
|
582
564
|
_keys = fetch_pipes_keys(
|
583
565
|
'registered',
|
584
566
|
get_web_connector(ctx.states),
|
585
|
-
connector_keys=
|
586
|
-
metric_keys=
|
587
|
-
location_keys=
|
588
|
-
tags=
|
567
|
+
connector_keys=connector_keys,
|
568
|
+
metric_keys=metric_keys,
|
569
|
+
location_keys=location_keys,
|
570
|
+
tags=tags,
|
589
571
|
)
|
590
572
|
_tags_pipes = mrsm.get_pipes(
|
591
|
-
connector_keys=
|
592
|
-
metric_keys=
|
593
|
-
location_keys=
|
594
|
-
tags=
|
573
|
+
connector_keys=connector_keys,
|
574
|
+
metric_keys=metric_keys,
|
575
|
+
location_keys=location_keys,
|
576
|
+
tags=tags,
|
595
577
|
instance=get_web_connector(ctx.states),
|
596
578
|
as_tags_dict=True,
|
597
579
|
)
|
598
580
|
_all_tags = list(
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
581
|
+
set(
|
582
|
+
mrsm.get_pipes(
|
583
|
+
instance=get_web_connector(ctx.states),
|
584
|
+
as_tags_dict=True,
|
585
|
+
)
|
586
|
+
).union(tags or [])
|
603
587
|
) if _tags_alone else []
|
604
588
|
except Exception as e:
|
605
589
|
instance_alerts += [alert_from_success_tuple((False, str(e)))]
|
606
|
-
_all_keys, _keys = [], []
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
590
|
+
_all_keys, _all_tags, _keys = [], [], []
|
591
|
+
|
592
|
+
connectors_options = sorted(
|
593
|
+
list(
|
594
|
+
set(
|
595
|
+
keys_tuple[0] for keys_tuple in (_all_keys if _ck_alone else _keys)
|
596
|
+
).union(set(connector_keys or []))
|
597
|
+
),
|
598
|
+
key=(lambda x: str(x).lower()),
|
599
|
+
)
|
600
|
+
metrics_options = sorted(
|
601
|
+
list(
|
602
|
+
set(
|
603
|
+
keys_tuple[1] for keys_tuple in (_all_keys if _mk_alone else _keys)
|
604
|
+
).union(set(metric_keys or []))
|
605
|
+
),
|
606
|
+
key=(lambda x: str(x).lower()),
|
607
|
+
)
|
608
|
+
locations_options = sorted(
|
609
|
+
list(
|
610
|
+
set(
|
611
|
+
(
|
612
|
+
str(keys_tuple[2])
|
613
|
+
for keys_tuple in (_all_keys if _lk_alone else _keys)
|
614
|
+
)
|
615
|
+
).union(set((str(_lk) for _lk in (location_keys or []))))
|
616
|
+
),
|
617
|
+
key=(lambda x: str(x).lower()),
|
618
|
+
)
|
619
|
+
|
620
|
+
tags_options = sorted(
|
621
|
+
list(
|
622
|
+
set(
|
623
|
+
(_all_tags if _tags_alone else _tags_pipes)
|
624
|
+
).union(set(tags or []))
|
625
|
+
),
|
626
|
+
key=(lambda x: str(x).lower()),
|
627
|
+
)
|
630
628
|
|
631
|
-
_connectors_options.sort(key=lambda x: str(x).lower())
|
632
|
-
_metrics_options.sort(key=lambda x: str(x).lower())
|
633
|
-
_locations_options.sort(key=lambda x: str(x).lower())
|
634
|
-
_tags_options.sort(key=lambda x: str(x).lower())
|
635
|
-
connector_keys = [
|
636
|
-
ck
|
637
|
-
for ck in connector_keys
|
638
|
-
if ck in [
|
639
|
-
_ck['value']
|
640
|
-
for _ck in _connectors_options
|
641
|
-
]
|
642
|
-
]
|
643
|
-
metric_keys = [
|
644
|
-
mk
|
645
|
-
for mk in metric_keys
|
646
|
-
if mk in [
|
647
|
-
_mk['value']
|
648
|
-
for _mk in _metrics_options
|
649
|
-
]
|
650
|
-
]
|
651
|
-
location_keys = [
|
652
|
-
lk
|
653
|
-
for lk in location_keys
|
654
|
-
if lk in [
|
655
|
-
_lk['value']
|
656
|
-
for _lk in _locations_options
|
657
|
-
]
|
658
|
-
]
|
659
|
-
tags = [
|
660
|
-
tag
|
661
|
-
for tag in tags
|
662
|
-
if tag in [
|
663
|
-
_tag['value']
|
664
|
-
for _tag in _tags_options
|
665
|
-
]
|
666
|
-
]
|
667
|
-
_connectors_datalist = [html.Option(value=o['value']) for o in _connectors_options]
|
668
|
-
_metrics_datalist = [html.Option(value=o['value']) for o in _metrics_options]
|
669
|
-
_locations_datalist = [html.Option(value=o['value']) for o in _locations_options]
|
670
|
-
_tags_datalist = [html.Option(value=o['value']) for o in _tags_options]
|
671
629
|
return (
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
_metrics_datalist,
|
677
|
-
metric_keys,
|
678
|
-
_locations_options,
|
679
|
-
_locations_datalist,
|
680
|
-
location_keys,
|
681
|
-
_tags_options,
|
682
|
-
_tags_datalist,
|
683
|
-
tags,
|
630
|
+
connectors_options,
|
631
|
+
metrics_options,
|
632
|
+
locations_options,
|
633
|
+
tags_options,
|
684
634
|
(instance_keys if update_instance_keys else dash.no_update),
|
685
635
|
instance_alerts,
|
686
636
|
)
|
687
637
|
|
638
|
+
|
639
|
+
@dash_app.callback(
|
640
|
+
Output('connector-keys-dropdown', 'value'),
|
641
|
+
Output('metric-keys-dropdown', 'value'),
|
642
|
+
Output('location-keys-dropdown', 'value'),
|
643
|
+
Output('tags-dropdown', 'value'),
|
644
|
+
Input('clear-all-keys-button', 'n_clicks'),
|
645
|
+
prevent_initial_call=True,
|
646
|
+
)
|
647
|
+
def clear_all_keys_button_click(n_clicks):
|
648
|
+
"""
|
649
|
+
Clear the keys dropdowns when the `Clear all` button is clicked.
|
650
|
+
"""
|
651
|
+
if not n_clicks:
|
652
|
+
raise PreventUpdate
|
653
|
+
|
654
|
+
return [], [], [], []
|
655
|
+
|
688
656
|
dash_app.clientside_callback(
|
689
657
|
"""
|
690
658
|
function(
|
@@ -856,6 +824,7 @@ dash_app.clientside_callback(
|
|
856
824
|
@dash_app.callback(
|
857
825
|
Output("download-dataframe-csv", "data"),
|
858
826
|
Input({'type': 'pipe-download-csv-button', 'index': ALL}, 'n_clicks'),
|
827
|
+
prevent_initial_call=True,
|
859
828
|
)
|
860
829
|
def download_pipe_csv(n_clicks):
|
861
830
|
"""
|
@@ -885,6 +854,7 @@ def download_pipe_csv(n_clicks):
|
|
885
854
|
Output({'type': 'pipe-accordion', 'index': MATCH}, 'children'),
|
886
855
|
Input({'type': 'pipe-accordion', 'index': MATCH}, 'active_item'),
|
887
856
|
State('session-store', 'data'),
|
857
|
+
prevent_initial_call=True,
|
888
858
|
)
|
889
859
|
def update_pipe_accordion(item, session_store_data):
|
890
860
|
"""
|
@@ -908,7 +878,8 @@ def update_pipe_accordion(item, session_store_data):
|
|
908
878
|
@dash_app.callback(
|
909
879
|
Output({'type': 'update-parameters-success-div', 'index': MATCH}, 'children'),
|
910
880
|
Input({'type': 'update-parameters-button', 'index': MATCH}, 'n_clicks'),
|
911
|
-
State({'type': 'parameters-editor', 'index': MATCH}, 'value')
|
881
|
+
State({'type': 'parameters-editor', 'index': MATCH}, 'value'),
|
882
|
+
prevent_initial_call=True,
|
912
883
|
)
|
913
884
|
def update_pipe_parameters_click(n_clicks, parameters_editor_text):
|
914
885
|
if not n_clicks:
|
@@ -942,6 +913,7 @@ def update_pipe_parameters_click(n_clicks, parameters_editor_text):
|
|
942
913
|
Output({'type': 'update-sql-success-div', 'index': MATCH}, 'children'),
|
943
914
|
Input({'type': 'update-sql-button', 'index': MATCH}, 'n_clicks'),
|
944
915
|
State({'type': 'sql-editor', 'index': MATCH}, 'value'),
|
916
|
+
prevent_initial_call=True,
|
945
917
|
)
|
946
918
|
def update_pipe_sql_click(n_clicks, sql_editor_text):
|
947
919
|
if not n_clicks:
|
@@ -968,7 +940,8 @@ def update_pipe_sql_click(n_clicks, sql_editor_text):
|
|
968
940
|
@dash_app.callback(
|
969
941
|
Output({'type': 'sync-success-div', 'index': MATCH}, 'children'),
|
970
942
|
Input({'type': 'update-sync-button', 'index': MATCH}, 'n_clicks'),
|
971
|
-
State({'type': 'sync-editor', 'index': MATCH}, 'value')
|
943
|
+
State({'type': 'sync-editor', 'index': MATCH}, 'value'),
|
944
|
+
prevent_initial_call=True,
|
972
945
|
)
|
973
946
|
def sync_documents_click(n_clicks, sync_editor_text):
|
974
947
|
if not n_clicks:
|
@@ -1014,6 +987,7 @@ def sync_documents_click(n_clicks, sync_editor_text):
|
|
1014
987
|
State({'type': 'limit-input', 'index': MATCH}, 'value'),
|
1015
988
|
State({'type': 'query-data-begin-input', 'index': MATCH}, 'value'),
|
1016
989
|
State({'type': 'query-data-end-input', 'index': MATCH}, 'value'),
|
990
|
+
prevent_initial_call=True,
|
1017
991
|
)
|
1018
992
|
def query_data_click(n_clicks, query_editor_text, limit_value, begin, end):
|
1019
993
|
triggered = dash.callback_context.triggered
|
@@ -1130,6 +1104,7 @@ def toggle_navbar_collapse(n_clicks: Optional[int], is_open: bool) -> bool:
|
|
1130
1104
|
Output('session-store', 'data'),
|
1131
1105
|
Input("sign-out-button", "n_clicks"),
|
1132
1106
|
State('session-store', 'data'),
|
1107
|
+
prevent_initial_call=True,
|
1133
1108
|
)
|
1134
1109
|
def sign_out_button_click(
|
1135
1110
|
n_clicks: Optional[int],
|
@@ -1150,6 +1125,7 @@ def sign_out_button_click(
|
|
1150
1125
|
Output({'type': 'parameters-editor', 'index': MATCH}, 'value'),
|
1151
1126
|
Input({'type': 'parameters-as-yaml-button', 'index': MATCH}, 'n_clicks'),
|
1152
1127
|
Input({'type': 'parameters-as-json-button', 'index': MATCH}, 'n_clicks'),
|
1128
|
+
prevent_initial_call=True,
|
1153
1129
|
)
|
1154
1130
|
def parameters_as_yaml_or_json_click(
|
1155
1131
|
yaml_n_clicks: Optional[int],
|
@@ -1178,6 +1154,7 @@ def parameters_as_yaml_or_json_click(
|
|
1178
1154
|
Output({'type': 'sync-editor', 'index': MATCH}, 'value'),
|
1179
1155
|
Input({'type': 'sync-as-json-button', 'index': MATCH}, 'n_clicks'),
|
1180
1156
|
Input({'type': 'sync-as-lines-button', 'index': MATCH}, 'n_clicks'),
|
1157
|
+
prevent_initial_call=True,
|
1181
1158
|
)
|
1182
1159
|
def sync_as_json_or_lines_click(
|
1183
1160
|
json_n_clicks: Optional[int],
|
@@ -1206,6 +1183,7 @@ def sync_as_json_or_lines_click(
|
|
1206
1183
|
Output('pages-offcanvas', 'children'),
|
1207
1184
|
Input('logo-img', 'n_clicks'),
|
1208
1185
|
State('pages-offcanvas', 'is_open'),
|
1186
|
+
prevent_initial_call=True,
|
1209
1187
|
)
|
1210
1188
|
def toggle_pages_offcanvas(n_clicks: Optional[int], is_open: bool):
|
1211
1189
|
"""
|
@@ -13,12 +13,13 @@ import time
|
|
13
13
|
import traceback
|
14
14
|
from datetime import datetime, timezone
|
15
15
|
|
16
|
+
from meerschaum.jobs import get_jobs
|
16
17
|
from meerschaum.utils.typing import Optional, Dict, Any
|
17
18
|
from meerschaum.api import CHECK_UPDATE
|
18
19
|
from meerschaum.api.dash import dash_app
|
19
20
|
from meerschaum.api.dash.sessions import get_username_from_session
|
20
21
|
from meerschaum.utils.packages import attempt_import, import_dcc, import_html
|
21
|
-
from meerschaum.api.dash.components import alert_from_success_tuple
|
22
|
+
from meerschaum.api.dash.components import alert_from_success_tuple, build_cards_grid
|
22
23
|
from meerschaum.api.dash.jobs import (
|
23
24
|
build_job_card,
|
24
25
|
build_manage_job_buttons_div_children,
|
@@ -251,17 +252,22 @@ def render_job_page_from_url(
|
|
251
252
|
session_data: Optional[Dict[str, Any]],
|
252
253
|
):
|
253
254
|
"""
|
254
|
-
Load the `/
|
255
|
+
Load the `/dash/jobs/{name}` page.
|
255
256
|
"""
|
256
|
-
if not str(pathname).startswith('/dash/
|
257
|
+
if not str(pathname).startswith('/dash/jobs'):
|
257
258
|
return no_update
|
258
259
|
|
259
260
|
session_id = (session_data or {}).get('session-id', None)
|
260
261
|
authenticated = is_session_authenticated(str(session_id))
|
261
262
|
|
262
|
-
job_name = pathname.replace('/dash/
|
263
|
+
job_name = pathname.replace('/dash/jobs', '').lstrip('/').rstrip('/')
|
263
264
|
if not job_name:
|
264
|
-
|
265
|
+
jobs = get_jobs(executor_keys='local', combine_local_and_systemd=True)
|
266
|
+
cards = [
|
267
|
+
build_job_card(job, authenticated=authenticated, include_follow=False)
|
268
|
+
for job in jobs.values()
|
269
|
+
]
|
270
|
+
return [html.Br(), build_cards_grid(cards, 3), html.Br()]
|
265
271
|
|
266
272
|
job = _get_job(job_name)
|
267
273
|
if not job.exists():
|