ansys-solutions-dash-super-components 0.2.dev7__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.
- ansys/solutions/dash_super_components/__init__.py +44 -0
- ansys/solutions/dash_super_components/assets/__init__.py +20 -0
- ansys/solutions/dash_super_components/assets/dashAgGridComponentFunctions.js +71 -0
- ansys/solutions/dash_super_components/authenticator.py +277 -0
- ansys/solutions/dash_super_components/dual_input_range_slider.py +397 -0
- ansys/solutions/dash_super_components/folder_selector.py +830 -0
- ansys/solutions/dash_super_components/input_form.py +908 -0
- ansys/solutions/dash_super_components/input_row_array.py +368 -0
- ansys/solutions/dash_super_components/logs_supervisor.py +887 -0
- ansys/solutions/dash_super_components/transaction_method_status_badge.py +366 -0
- ansys/solutions/dash_super_components/transaction_supervisor.py +587 -0
- ansys/solutions/dash_super_components/tree.py +396 -0
- ansys/solutions/dash_super_components/utils/__init__.py +18 -0
- ansys/solutions/dash_super_components/utils/aio_ids.py +83 -0
- ansys/solutions/dash_super_components/utils/api_requests.py +69 -0
- ansys/solutions/dash_super_components/utils/assets_server.py +52 -0
- ansys/solutions/dash_super_components/utils/config.py +77 -0
- ansys/solutions/dash_super_components/utils/logs_parser.py +151 -0
- ansys/solutions/dash_super_components/utils/path_validator.py +163 -0
- ansys/solutions/dash_super_components/utils/status_badge_properties.py +60 -0
- ansys/solutions/dash_super_components/utils/svg_icons.py +395 -0
- ansys_solutions_dash_super_components-0.2.dev7.dist-info/METADATA +169 -0
- ansys_solutions_dash_super_components-0.2.dev7.dist-info/RECORD +26 -0
- ansys_solutions_dash_super_components-0.2.dev7.dist-info/WHEEL +4 -0
- ansys_solutions_dash_super_components-0.2.dev7.dist-info/licenses/AUTHORS +12 -0
- ansys_solutions_dash_super_components-0.2.dev7.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
# Copyright (C) 2026 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
"""Provides a Dash component for tracking the status of SAF transaction method."""
|
|
19
|
+
|
|
20
|
+
from datetime import datetime, timedelta
|
|
21
|
+
import time
|
|
22
|
+
from typing import Any
|
|
23
|
+
import uuid
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
# dash >=3.2.0
|
|
27
|
+
from dash import NoUpdate
|
|
28
|
+
except ImportError:
|
|
29
|
+
# dash >=2.18.2, <3.2.0
|
|
30
|
+
from dash._callback import NoUpdate # pyright: ignore[reportPrivateImportUsage]
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
# dash-extensions < 2.0.5
|
|
34
|
+
from dash_extensions.enrich import _Wildcard # pyright: ignore[reportAttributeAccessIssue]
|
|
35
|
+
except ImportError:
|
|
36
|
+
# dash-extensions >= 2.0.5
|
|
37
|
+
from dash_extensions.enrich import (
|
|
38
|
+
Wildcard as _Wildcard, # pyright: ignore[reportAttributeAccessIssue]
|
|
39
|
+
)
|
|
40
|
+
from dash_extensions.enrich import (
|
|
41
|
+
MATCH,
|
|
42
|
+
Input,
|
|
43
|
+
Output,
|
|
44
|
+
State,
|
|
45
|
+
callback,
|
|
46
|
+
dcc,
|
|
47
|
+
html,
|
|
48
|
+
no_update,
|
|
49
|
+
)
|
|
50
|
+
import dash_mantine_components as dmc
|
|
51
|
+
|
|
52
|
+
from ansys.solutions.dash_super_components.utils.aio_ids import AIOIds
|
|
53
|
+
from ansys.solutions.dash_super_components.utils.api_requests import GlowAPIRequest
|
|
54
|
+
from ansys.solutions.dash_super_components.utils.svg_icons import IconNames, create_base64_svg_src
|
|
55
|
+
|
|
56
|
+
TRANSACTION_STATUS_BADGE_PROPERTIES = {
|
|
57
|
+
"run-required": {
|
|
58
|
+
"color": "gray",
|
|
59
|
+
},
|
|
60
|
+
"running": {
|
|
61
|
+
"color": "indigo",
|
|
62
|
+
},
|
|
63
|
+
"completed": {
|
|
64
|
+
"color": "lime",
|
|
65
|
+
},
|
|
66
|
+
"failed": {
|
|
67
|
+
"color": "red",
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TransactionSupervisor(html.Div):
|
|
73
|
+
"""
|
|
74
|
+
A Dash component for monitoring the status of a SAF GLOW transaction method.
|
|
75
|
+
|
|
76
|
+
TransactionSupervisor is based on the Dash All-in-One (AIO) component pattern. It polls
|
|
77
|
+
the GLOW API to track method status in real time and displays elapsed time, started time,
|
|
78
|
+
and a color-coded status badge.
|
|
79
|
+
|
|
80
|
+
.. warning::
|
|
81
|
+
|
|
82
|
+
This component requires a SAF-based solution with access to the GLOW API. It must
|
|
83
|
+
be instantiated inside a callback (not directly in the layout) because it needs the
|
|
84
|
+
project URL from ``DashClient``.
|
|
85
|
+
|
|
86
|
+
To activate monitoring from a callback use::
|
|
87
|
+
|
|
88
|
+
TransactionSupervisor.ids.activate_supervision(aio_id) # Store; set to True
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
url : str
|
|
93
|
+
The URL of the GLOW API server.
|
|
94
|
+
step_name : str
|
|
95
|
+
The name of the GLOW step (StepModel) that contains the method.
|
|
96
|
+
method_name : str
|
|
97
|
+
The name of the GLOW transaction method whose status is being monitored.
|
|
98
|
+
title : str, optional
|
|
99
|
+
Title displayed in the monitoring card.
|
|
100
|
+
show : bool, optional
|
|
101
|
+
Whether to show the monitoring card. Default is ``True``.
|
|
102
|
+
aio_id : str, optional
|
|
103
|
+
Unique identifier for this component instance. A UUID is generated when
|
|
104
|
+
not provided.
|
|
105
|
+
width : str or int, optional
|
|
106
|
+
Width of the monitoring card. Default is ``400``.
|
|
107
|
+
fontsize : str, optional
|
|
108
|
+
Font size of the text in the card. Default is ``'14px'``.
|
|
109
|
+
title_fontsize : str, optional
|
|
110
|
+
Font size of the title in the card. Default is ``'16px'``.
|
|
111
|
+
orientation : str, optional
|
|
112
|
+
Layout orientation of the card (``'horizontal'`` or ``'vertical'``).
|
|
113
|
+
Default is ``'horizontal'``.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
class TransactionSupervisorIds(AIOIds):
|
|
117
|
+
"""Provides IDs for the subcomponents of :class:`TransactionSupervisor`."""
|
|
118
|
+
|
|
119
|
+
@classmethod
|
|
120
|
+
def _monitoring_data(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
121
|
+
"""Return the ID for the monitoring data store.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
aio_id : str or _Wildcard
|
|
126
|
+
The component's unique identifier.
|
|
127
|
+
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
dict[str, Any]
|
|
131
|
+
The unique ID dictionary for the monitoring data store subcomponent.
|
|
132
|
+
"""
|
|
133
|
+
return cls.make_id_dict("transaction-supervisor", "monitoring-data", aio_id)
|
|
134
|
+
|
|
135
|
+
@classmethod
|
|
136
|
+
def _loader(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
137
|
+
"""Return the ID for the loader store.
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
aio_id : str or _Wildcard
|
|
142
|
+
The component's unique identifier.
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
dict[str, Any]
|
|
147
|
+
The unique ID dictionary for the loader store subcomponent.
|
|
148
|
+
"""
|
|
149
|
+
return cls.make_id_dict("transaction-supervisor", "loader", aio_id)
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def _interval(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
153
|
+
"""Return the ID for the interval component.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
aio_id : str or _Wildcard
|
|
158
|
+
The component's unique identifier.
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
dict[str, Any]
|
|
163
|
+
The unique ID dictionary for the interval subcomponent.
|
|
164
|
+
"""
|
|
165
|
+
return cls.make_id_dict("transaction-supervisor", "interval", aio_id)
|
|
166
|
+
|
|
167
|
+
@classmethod
|
|
168
|
+
def _container(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
169
|
+
"""Return the ID for the container component.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
aio_id : str or _Wildcard
|
|
174
|
+
The component's unique identifier.
|
|
175
|
+
|
|
176
|
+
Returns
|
|
177
|
+
-------
|
|
178
|
+
dict[str, Any]
|
|
179
|
+
The unique ID dictionary for the container subcomponent.
|
|
180
|
+
"""
|
|
181
|
+
return cls.make_id_dict("transaction-supervisor", "container", aio_id)
|
|
182
|
+
|
|
183
|
+
@classmethod
|
|
184
|
+
def activate_supervision(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
185
|
+
"""Return the ID for the activate supervision store.
|
|
186
|
+
|
|
187
|
+
Parameters
|
|
188
|
+
----------
|
|
189
|
+
aio_id : str or _Wildcard
|
|
190
|
+
The component's unique identifier.
|
|
191
|
+
|
|
192
|
+
Returns
|
|
193
|
+
-------
|
|
194
|
+
dict[str, Any]
|
|
195
|
+
The unique ID dictionary for the activate supervision store subcomponent.
|
|
196
|
+
"""
|
|
197
|
+
return cls.make_id_dict("transaction-supervisor", "activate-supervision", aio_id)
|
|
198
|
+
|
|
199
|
+
@classmethod
|
|
200
|
+
def transaction_status_badge(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
201
|
+
"""Return the ID for the transaction status badge.
|
|
202
|
+
|
|
203
|
+
Parameters
|
|
204
|
+
----------
|
|
205
|
+
aio_id : str or _Wildcard
|
|
206
|
+
The component's unique identifier.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
dict[str, Any]
|
|
211
|
+
The unique ID dictionary for the transaction status badge subcomponent.
|
|
212
|
+
"""
|
|
213
|
+
return cls.make_id_dict("transaction-supervisor", "transaction-status-badge", aio_id)
|
|
214
|
+
|
|
215
|
+
@classmethod
|
|
216
|
+
def started_time_label(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
217
|
+
"""Return the ID for the started time label.
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
aio_id : str or _Wildcard
|
|
222
|
+
The component's unique identifier.
|
|
223
|
+
|
|
224
|
+
Returns
|
|
225
|
+
-------
|
|
226
|
+
dict[str, Any]
|
|
227
|
+
The unique ID dictionary for the started time label subcomponent.
|
|
228
|
+
"""
|
|
229
|
+
return cls.make_id_dict("transaction-supervisor", "started-time-label", aio_id)
|
|
230
|
+
|
|
231
|
+
@classmethod
|
|
232
|
+
def elapsed_time_label(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
233
|
+
"""Return the ID for the elapsed time label.
|
|
234
|
+
|
|
235
|
+
Parameters
|
|
236
|
+
----------
|
|
237
|
+
aio_id : str or _Wildcard
|
|
238
|
+
The component's unique identifier.
|
|
239
|
+
|
|
240
|
+
Returns
|
|
241
|
+
-------
|
|
242
|
+
dict[str, Any]
|
|
243
|
+
The unique ID dictionary for the elapsed time label subcomponent.
|
|
244
|
+
"""
|
|
245
|
+
return cls.make_id_dict("transaction-supervisor", "elapsed-time-label", aio_id)
|
|
246
|
+
|
|
247
|
+
@classmethod
|
|
248
|
+
def switch(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
|
|
249
|
+
"""Return the ID for the switch component.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
aio_id : str or _Wildcard
|
|
254
|
+
The component's unique identifier.
|
|
255
|
+
|
|
256
|
+
Returns
|
|
257
|
+
-------
|
|
258
|
+
dict[str, Any]
|
|
259
|
+
The unique ID dictionary for the switch subcomponent.
|
|
260
|
+
"""
|
|
261
|
+
return cls.make_id_dict("transaction-supervisor", "switch", aio_id)
|
|
262
|
+
|
|
263
|
+
ids = TransactionSupervisorIds
|
|
264
|
+
|
|
265
|
+
def __init__(
|
|
266
|
+
self,
|
|
267
|
+
url: str,
|
|
268
|
+
step_name: str,
|
|
269
|
+
method_name: str,
|
|
270
|
+
title: str = "Transaction Supervisor",
|
|
271
|
+
show: bool = True,
|
|
272
|
+
aio_id: str | None = None,
|
|
273
|
+
width: str | int = 400,
|
|
274
|
+
fontsize: str = "14px",
|
|
275
|
+
title_fontsize: str = "16px",
|
|
276
|
+
orientation: str = "horizontal",
|
|
277
|
+
):
|
|
278
|
+
self._url = url
|
|
279
|
+
self._step_name = step_name
|
|
280
|
+
self._method_name = method_name
|
|
281
|
+
self._title = title
|
|
282
|
+
self._show = show
|
|
283
|
+
self._width = width
|
|
284
|
+
self._fontsize = fontsize
|
|
285
|
+
self._orientation = orientation
|
|
286
|
+
self._title_fontsize = title_fontsize
|
|
287
|
+
self.aio_id = aio_id if aio_id is not None else str(uuid.uuid4())
|
|
288
|
+
|
|
289
|
+
super().__init__(
|
|
290
|
+
[
|
|
291
|
+
html.Div(
|
|
292
|
+
[
|
|
293
|
+
dcc.Store(
|
|
294
|
+
id=self.ids._monitoring_data(self.aio_id),
|
|
295
|
+
storage_type="session",
|
|
296
|
+
data={
|
|
297
|
+
"url": url,
|
|
298
|
+
"step_name": self._step_name,
|
|
299
|
+
"method_name": self._method_name,
|
|
300
|
+
},
|
|
301
|
+
),
|
|
302
|
+
dcc.Store(
|
|
303
|
+
id=self.ids.activate_supervision(self.aio_id),
|
|
304
|
+
storage_type="session",
|
|
305
|
+
data=False,
|
|
306
|
+
),
|
|
307
|
+
dcc.Interval(
|
|
308
|
+
id=self.ids._interval(self.aio_id),
|
|
309
|
+
interval=1000,
|
|
310
|
+
n_intervals=0,
|
|
311
|
+
disabled=True,
|
|
312
|
+
),
|
|
313
|
+
dmc.Card(
|
|
314
|
+
children=[
|
|
315
|
+
dmc.CardSection(
|
|
316
|
+
dmc.Group(
|
|
317
|
+
children=[
|
|
318
|
+
html.Div(
|
|
319
|
+
self._title,
|
|
320
|
+
style={
|
|
321
|
+
"display": "inline-block",
|
|
322
|
+
"fontSize": self._title_fontsize,
|
|
323
|
+
},
|
|
324
|
+
),
|
|
325
|
+
dcc.Loading(
|
|
326
|
+
id=self.ids._loader(self.aio_id),
|
|
327
|
+
display="hide",
|
|
328
|
+
),
|
|
329
|
+
dmc.HoverCard(
|
|
330
|
+
children=[
|
|
331
|
+
dmc.HoverCardTarget(
|
|
332
|
+
dmc.Switch(
|
|
333
|
+
id=self.ids.switch(
|
|
334
|
+
self.aio_id,
|
|
335
|
+
),
|
|
336
|
+
checked=self._show,
|
|
337
|
+
offLabel=html.Img(
|
|
338
|
+
src=create_base64_svg_src(
|
|
339
|
+
IconNames.MDI_HIDE,
|
|
340
|
+
),
|
|
341
|
+
),
|
|
342
|
+
onLabel=html.Img(
|
|
343
|
+
src=create_base64_svg_src(
|
|
344
|
+
IconNames.MDI_SHOW,
|
|
345
|
+
color="#fff",
|
|
346
|
+
),
|
|
347
|
+
),
|
|
348
|
+
size="sm",
|
|
349
|
+
),
|
|
350
|
+
),
|
|
351
|
+
dmc.HoverCardDropdown(
|
|
352
|
+
dmc.Text(
|
|
353
|
+
"Show/Hide monitoring panel.",
|
|
354
|
+
size="sm",
|
|
355
|
+
),
|
|
356
|
+
),
|
|
357
|
+
],
|
|
358
|
+
withArrow=True,
|
|
359
|
+
shadow="md",
|
|
360
|
+
),
|
|
361
|
+
],
|
|
362
|
+
justify="space-around",
|
|
363
|
+
),
|
|
364
|
+
withBorder=True,
|
|
365
|
+
inheritPadding=True,
|
|
366
|
+
py="xs",
|
|
367
|
+
),
|
|
368
|
+
html.Div(
|
|
369
|
+
dmc.Grid(
|
|
370
|
+
children=[
|
|
371
|
+
dmc.GridCol(
|
|
372
|
+
html.Div(
|
|
373
|
+
[
|
|
374
|
+
html.Div(
|
|
375
|
+
"Transaction method status :",
|
|
376
|
+
style={
|
|
377
|
+
"display": "inline-block",
|
|
378
|
+
"fontSize": self._fontsize,
|
|
379
|
+
"marginTop": "5px",
|
|
380
|
+
},
|
|
381
|
+
),
|
|
382
|
+
html.Div(
|
|
383
|
+
dmc.Badge(
|
|
384
|
+
id=self.ids.transaction_status_badge(
|
|
385
|
+
self.aio_id,
|
|
386
|
+
),
|
|
387
|
+
style={
|
|
388
|
+
"fontSize": self._fontsize,
|
|
389
|
+
},
|
|
390
|
+
),
|
|
391
|
+
style={
|
|
392
|
+
"marginLeft": "5px",
|
|
393
|
+
"display": "inline-block",
|
|
394
|
+
},
|
|
395
|
+
),
|
|
396
|
+
],
|
|
397
|
+
style={"display": "inline-block"},
|
|
398
|
+
),
|
|
399
|
+
span=(
|
|
400
|
+
"content"
|
|
401
|
+
if self._orientation == "horizontal"
|
|
402
|
+
else 12
|
|
403
|
+
),
|
|
404
|
+
),
|
|
405
|
+
dmc.GridCol(
|
|
406
|
+
html.Div(
|
|
407
|
+
[
|
|
408
|
+
html.Div(
|
|
409
|
+
"Started time :",
|
|
410
|
+
style={
|
|
411
|
+
"display": "inline-block",
|
|
412
|
+
"fontSize": self._fontsize,
|
|
413
|
+
"marginTop": "5px",
|
|
414
|
+
},
|
|
415
|
+
),
|
|
416
|
+
html.Div(
|
|
417
|
+
id=self.ids.started_time_label(
|
|
418
|
+
self.aio_id,
|
|
419
|
+
),
|
|
420
|
+
style={
|
|
421
|
+
"display": "inline-block",
|
|
422
|
+
"fontSize": self._fontsize,
|
|
423
|
+
"marginTop": "5px",
|
|
424
|
+
"marginLeft": "5px",
|
|
425
|
+
},
|
|
426
|
+
),
|
|
427
|
+
],
|
|
428
|
+
style={"display": "inline-block"},
|
|
429
|
+
),
|
|
430
|
+
span=(
|
|
431
|
+
"content"
|
|
432
|
+
if self._orientation == "horizontal"
|
|
433
|
+
else 12
|
|
434
|
+
),
|
|
435
|
+
),
|
|
436
|
+
dmc.GridCol(
|
|
437
|
+
html.Div(
|
|
438
|
+
[
|
|
439
|
+
html.Div(
|
|
440
|
+
"Elapsed time :",
|
|
441
|
+
style={
|
|
442
|
+
"display": "inline-block",
|
|
443
|
+
"fontSize": self._fontsize,
|
|
444
|
+
"marginTop": "5px",
|
|
445
|
+
},
|
|
446
|
+
),
|
|
447
|
+
html.Div(
|
|
448
|
+
id=self.ids.elapsed_time_label(
|
|
449
|
+
self.aio_id,
|
|
450
|
+
),
|
|
451
|
+
style={
|
|
452
|
+
"display": "inline-block",
|
|
453
|
+
"fontSize": self._fontsize,
|
|
454
|
+
"marginTop": "5px",
|
|
455
|
+
"marginLeft": "5px",
|
|
456
|
+
},
|
|
457
|
+
),
|
|
458
|
+
],
|
|
459
|
+
style={"display": "inline-block"},
|
|
460
|
+
),
|
|
461
|
+
span=(
|
|
462
|
+
"content"
|
|
463
|
+
if self._orientation == "horizontal"
|
|
464
|
+
else 12
|
|
465
|
+
),
|
|
466
|
+
),
|
|
467
|
+
],
|
|
468
|
+
gutter="xs",
|
|
469
|
+
),
|
|
470
|
+
id=self.ids._container(self.aio_id),
|
|
471
|
+
style={
|
|
472
|
+
"display": "inline-block",
|
|
473
|
+
},
|
|
474
|
+
),
|
|
475
|
+
],
|
|
476
|
+
withBorder=True,
|
|
477
|
+
shadow="sm",
|
|
478
|
+
radius="md",
|
|
479
|
+
w=self._width,
|
|
480
|
+
),
|
|
481
|
+
],
|
|
482
|
+
),
|
|
483
|
+
],
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
@staticmethod
|
|
487
|
+
@callback(
|
|
488
|
+
Output(ids._container(MATCH), "style"),
|
|
489
|
+
Input(ids.switch(MATCH), "checked"),
|
|
490
|
+
)
|
|
491
|
+
def show_supervision_card(
|
|
492
|
+
checked: bool,
|
|
493
|
+
) -> dict[str, Any]:
|
|
494
|
+
"""Hide or show the content of the supervision card."""
|
|
495
|
+
return {"display": "inline-block"} if checked else {"display": "none"}
|
|
496
|
+
|
|
497
|
+
@staticmethod
|
|
498
|
+
@callback(
|
|
499
|
+
Output(ids._interval(MATCH), "disabled"),
|
|
500
|
+
Output(ids._monitoring_data(MATCH), "data", allow_duplicate=True),
|
|
501
|
+
Output(ids._loader(MATCH), "display"),
|
|
502
|
+
Input(ids.activate_supervision(MATCH), "data"),
|
|
503
|
+
State(ids._monitoring_data(MATCH), "data"),
|
|
504
|
+
prevent_initial_call=True,
|
|
505
|
+
)
|
|
506
|
+
def start_stop_supervision(
|
|
507
|
+
supervision_active: bool,
|
|
508
|
+
data: dict[str, str],
|
|
509
|
+
) -> tuple[bool, dict[str, str] | NoUpdate, str]:
|
|
510
|
+
"""Start the monitoring of the transaction method."""
|
|
511
|
+
if not supervision_active:
|
|
512
|
+
return True, no_update, "hide"
|
|
513
|
+
|
|
514
|
+
# Reset timing data for a new transaction run
|
|
515
|
+
data["started_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
|
|
516
|
+
data["elapsed_time"] = str(timedelta(0))
|
|
517
|
+
# set the loader display to show
|
|
518
|
+
loader_display = "show"
|
|
519
|
+
|
|
520
|
+
return not supervision_active, data, loader_display
|
|
521
|
+
|
|
522
|
+
@staticmethod
|
|
523
|
+
@callback(
|
|
524
|
+
Output(ids.started_time_label(MATCH), "children", allow_duplicate=True),
|
|
525
|
+
Output(ids.elapsed_time_label(MATCH), "children", allow_duplicate=True),
|
|
526
|
+
Input(ids._monitoring_data(MATCH), "data"),
|
|
527
|
+
)
|
|
528
|
+
def update_time_labels(
|
|
529
|
+
data: dict[str, str],
|
|
530
|
+
) -> tuple[str, str]:
|
|
531
|
+
"""Update the started time and elapsed time labels."""
|
|
532
|
+
started_time = data.get("started_time", "")
|
|
533
|
+
elapsed_time = data.get("elapsed_time", str(timedelta(0)))
|
|
534
|
+
return started_time, elapsed_time
|
|
535
|
+
|
|
536
|
+
@staticmethod
|
|
537
|
+
@callback(
|
|
538
|
+
Output(ids.transaction_status_badge(MATCH), "children"),
|
|
539
|
+
Output(ids.transaction_status_badge(MATCH), "color"),
|
|
540
|
+
Output(ids.activate_supervision(MATCH), "data", allow_duplicate=True),
|
|
541
|
+
Output(ids._monitoring_data(MATCH), "data", allow_duplicate=True),
|
|
542
|
+
Input(ids._interval(MATCH), "n_intervals"),
|
|
543
|
+
State(ids._monitoring_data(MATCH), "data"),
|
|
544
|
+
State(ids.activate_supervision(MATCH), "data"),
|
|
545
|
+
)
|
|
546
|
+
def update_supervision_card(
|
|
547
|
+
n_intervals: int,
|
|
548
|
+
data: dict[str, str],
|
|
549
|
+
supervision_active: bool,
|
|
550
|
+
) -> tuple[str, str, bool | NoUpdate, dict[str, str] | NoUpdate]:
|
|
551
|
+
"""Update the supervision data and stop supervision when transaction has finished."""
|
|
552
|
+
glow_api_request = GlowAPIRequest(data["url"])
|
|
553
|
+
method_status = glow_api_request.get_transaction_method_status(
|
|
554
|
+
data["step_name"],
|
|
555
|
+
data["method_name"],
|
|
556
|
+
)
|
|
557
|
+
color = TRANSACTION_STATUS_BADGE_PROPERTIES[method_status]["color"]
|
|
558
|
+
|
|
559
|
+
if not supervision_active:
|
|
560
|
+
return (
|
|
561
|
+
method_status,
|
|
562
|
+
color,
|
|
563
|
+
no_update,
|
|
564
|
+
no_update,
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
# Stop supervision if method has finished
|
|
568
|
+
supervisor_active = False if method_status.lower() in ["completed", "failed"] else no_update
|
|
569
|
+
|
|
570
|
+
current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
|
|
571
|
+
started_time = data.get("started_time", "")
|
|
572
|
+
if not started_time:
|
|
573
|
+
# no started_time found in data (e.g. first time page load when method still "running")
|
|
574
|
+
elapsed_time = str(timedelta(0))
|
|
575
|
+
else:
|
|
576
|
+
elapsed_time = str(
|
|
577
|
+
datetime.strptime(current_time, "%Y-%m-%d %H:%M:%S")
|
|
578
|
+
- datetime.strptime(started_time, "%Y-%m-%d %H:%M:%S"),
|
|
579
|
+
)
|
|
580
|
+
data["elapsed_time"] = elapsed_time
|
|
581
|
+
|
|
582
|
+
return (
|
|
583
|
+
method_status,
|
|
584
|
+
color,
|
|
585
|
+
supervisor_active,
|
|
586
|
+
data,
|
|
587
|
+
)
|