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.
Files changed (26) hide show
  1. ansys/solutions/dash_super_components/__init__.py +44 -0
  2. ansys/solutions/dash_super_components/assets/__init__.py +20 -0
  3. ansys/solutions/dash_super_components/assets/dashAgGridComponentFunctions.js +71 -0
  4. ansys/solutions/dash_super_components/authenticator.py +277 -0
  5. ansys/solutions/dash_super_components/dual_input_range_slider.py +397 -0
  6. ansys/solutions/dash_super_components/folder_selector.py +830 -0
  7. ansys/solutions/dash_super_components/input_form.py +908 -0
  8. ansys/solutions/dash_super_components/input_row_array.py +368 -0
  9. ansys/solutions/dash_super_components/logs_supervisor.py +887 -0
  10. ansys/solutions/dash_super_components/transaction_method_status_badge.py +366 -0
  11. ansys/solutions/dash_super_components/transaction_supervisor.py +587 -0
  12. ansys/solutions/dash_super_components/tree.py +396 -0
  13. ansys/solutions/dash_super_components/utils/__init__.py +18 -0
  14. ansys/solutions/dash_super_components/utils/aio_ids.py +83 -0
  15. ansys/solutions/dash_super_components/utils/api_requests.py +69 -0
  16. ansys/solutions/dash_super_components/utils/assets_server.py +52 -0
  17. ansys/solutions/dash_super_components/utils/config.py +77 -0
  18. ansys/solutions/dash_super_components/utils/logs_parser.py +151 -0
  19. ansys/solutions/dash_super_components/utils/path_validator.py +163 -0
  20. ansys/solutions/dash_super_components/utils/status_badge_properties.py +60 -0
  21. ansys/solutions/dash_super_components/utils/svg_icons.py +395 -0
  22. ansys_solutions_dash_super_components-0.2.dev7.dist-info/METADATA +169 -0
  23. ansys_solutions_dash_super_components-0.2.dev7.dist-info/RECORD +26 -0
  24. ansys_solutions_dash_super_components-0.2.dev7.dist-info/WHEEL +4 -0
  25. ansys_solutions_dash_super_components-0.2.dev7.dist-info/licenses/AUTHORS +12 -0
  26. ansys_solutions_dash_super_components-0.2.dev7.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,368 @@
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
+ """Input Row Array component."""
19
+
20
+ from typing import Any, TypeVar
21
+ import uuid
22
+
23
+ from dash.exceptions import PreventUpdate
24
+
25
+ try:
26
+ # dash-extensions < 2.0.5
27
+ from dash_extensions.enrich import _Wildcard # pyright: ignore[reportAttributeAccessIssue]
28
+ except ImportError:
29
+ # dash-extensions >= 2.0.5
30
+ from dash_extensions.enrich import (
31
+ Wildcard as _Wildcard, # pyright: ignore[reportAttributeAccessIssue]
32
+ )
33
+ from dash_extensions.enrich import MATCH, Input, Output, State, callback, dcc, html
34
+ import dash_mantine_components as dmc
35
+
36
+ from ansys.solutions.dash_super_components.utils.aio_ids import AIOIds
37
+ from ansys.solutions.dash_super_components.utils.svg_icons import IconNames, create_base64_svg_src
38
+
39
+ T = TypeVar("T", dmc.TextInput, dmc.NumberInput, dmc.Select)
40
+
41
+ default_text_input_props = {
42
+ "label": "Field",
43
+ "placeholder": "Enter your data.",
44
+ "required": True,
45
+ "disabled": False,
46
+ "style": {"width": "100%"},
47
+ }
48
+
49
+
50
+ default_number_input_props = {
51
+ "label": "Field",
52
+ "placeholder": "Enter your data.",
53
+ "required": True,
54
+ "disabled": False,
55
+ "style": {"width": "100%"},
56
+ }
57
+
58
+
59
+ default_select_props = {
60
+ "label": "Field",
61
+ "placeholder": "Enter your data.",
62
+ "required": True,
63
+ "disabled": False,
64
+ "style": {"width": "100%"},
65
+ }
66
+
67
+
68
+ class InputRowArray(html.Div):
69
+ """
70
+ A Dash component to create an array of inputs.
71
+
72
+ InputRowArray is based on the Dash All-in-One (AIO) component pattern.
73
+ It renders a set of input fields as a single row, and optionally allows
74
+ users to add or remove additional rows dynamically.
75
+
76
+ Each field is defined by a dict with the following keys:
77
+
78
+ - ``"type"`` *(required)*: ``"TextInput"``, ``"NumberInput"``, or ``"Select"``.
79
+ - ``"id"`` *(required)*: unique string identifier for the field.
80
+ - ``"properties"`` *(required)*: dict of dash mantine component properties.
81
+
82
+ Parameters
83
+ ----------
84
+ items_definition : list of dict
85
+ A list of dictionaries defining each input field in a row. Each dict
86
+ must contain ``"type"``, ``"id"``, and ``"properties"`` keys.
87
+ Supported types: ``"TextInput"``, ``"NumberInput"``, ``"Select"``.
88
+ enable_multiple_rows : bool, optional
89
+ If ``True``, add and delete buttons are displayed so that users can
90
+ create or remove extra rows at runtime. Default is ``False``.
91
+ aio_id : str, optional
92
+ The unique identifier for the component. A UUID is generated if not
93
+ provided.
94
+ """
95
+
96
+ class InputRowArrayIds(AIOIds):
97
+ """Provides IDs for the subcomponents of :class:`InputRowArray`."""
98
+
99
+ @classmethod
100
+ def _make_id_dict_with_identifier_and_row_index(
101
+ cls,
102
+ subcomponent: str,
103
+ aio_id: str | _Wildcard,
104
+ identifier: str | _Wildcard,
105
+ row_index: int | None | _Wildcard,
106
+ ) -> dict[str, Any]:
107
+ id_dict = cls.make_id_dict("input-row-array", subcomponent, aio_id)
108
+ id_dict["identifier"] = identifier
109
+ id_dict["row_index"] = row_index
110
+ return id_dict
111
+
112
+ @classmethod
113
+ def _storage(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
114
+ """Return the ID for the storage component.
115
+
116
+ Parameters
117
+ ----------
118
+ aio_id : str or _Wildcard
119
+ The component's unique identifier.
120
+
121
+ Returns
122
+ -------
123
+ dict[str, Any]
124
+ The unique ID dictionary for the storage subcomponent.
125
+ """
126
+ return cls.make_id_dict("input-row-array", "storage", aio_id)
127
+
128
+ @classmethod
129
+ def add_button(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
130
+ """Return the ID for the add button component.
131
+
132
+ Parameters
133
+ ----------
134
+ aio_id : str or _Wildcard
135
+ The component's unique identifier.
136
+
137
+ Returns
138
+ -------
139
+ dict[str, Any]
140
+ The unique ID dictionary for the add button subcomponent.
141
+ """
142
+ return cls.make_id_dict("input-row-array", "add-button", aio_id)
143
+
144
+ @classmethod
145
+ def delete_button(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
146
+ """Return the ID for the delete button component.
147
+
148
+ Parameters
149
+ ----------
150
+ aio_id : str or _Wildcard
151
+ The component's unique identifier.
152
+
153
+ Returns
154
+ -------
155
+ dict[str, Any]
156
+ The unique ID dictionary for the delete button subcomponent.
157
+ """
158
+ return cls.make_id_dict("input-row-array", "delete-button", aio_id)
159
+
160
+ @classmethod
161
+ def rows(cls, aio_id: str | _Wildcard) -> dict[str, Any]:
162
+ """Return the ID for the rows component.
163
+
164
+ Parameters
165
+ ----------
166
+ aio_id : str or _Wildcard
167
+ The component's unique identifier.
168
+
169
+ Returns
170
+ -------
171
+ dict[str, Any]
172
+ The unique ID dictionary for the rows subcomponent.
173
+ """
174
+ return cls.make_id_dict("input-row-array", "rows", aio_id)
175
+
176
+ @classmethod
177
+ def input(
178
+ cls,
179
+ aio_id: str | _Wildcard,
180
+ item_id: str | _Wildcard,
181
+ row_index: int | None | _Wildcard = None,
182
+ ) -> dict[str, Any]:
183
+ """Return the ID for an input item.
184
+
185
+ Parameters
186
+ ----------
187
+ aio_id : str or _Wildcard
188
+ The component's unique identifier.
189
+ item_id : str or _Wildcard
190
+ The unique identifier of the input item (item["id"]).
191
+ row_index : int, None, or _Wildcard, default: None
192
+ The unique row index. If ``None``, defaults to 0.
193
+
194
+ Returns
195
+ -------
196
+ dict[str, Any]
197
+ The unique ID dictionary for an input item subcomponent.
198
+ """
199
+ if row_index is None:
200
+ row_index = 0
201
+
202
+ return cls._make_id_dict_with_identifier_and_row_index(
203
+ "input", aio_id, item_id, row_index
204
+ )
205
+
206
+ ids = InputRowArrayIds
207
+
208
+ def __init__(
209
+ self,
210
+ items_definition: list[dict[str, Any]],
211
+ enable_multiple_rows: bool = False,
212
+ aio_id: str | None = None,
213
+ ):
214
+ self.aio_id = aio_id if aio_id is not None else str(uuid.uuid4())
215
+
216
+ layout: list[dmc.Group | html.Div | dcc.Store] = []
217
+
218
+ if enable_multiple_rows:
219
+ layout.append(
220
+ dmc.Group(
221
+ [
222
+ dmc.ActionIcon(
223
+ html.Img(
224
+ src=create_base64_svg_src(IconNames.MATERIAL_ADD, color="#fff"),
225
+ ),
226
+ size="md",
227
+ variant="filled",
228
+ color="blue",
229
+ id=self.ids.add_button(self.aio_id),
230
+ ),
231
+ dmc.ActionIcon(
232
+ html.Img(
233
+ src=create_base64_svg_src(IconNames.MATERIAL_REMOVE, color="#fff"),
234
+ ),
235
+ size="md",
236
+ variant="filled",
237
+ color="blue",
238
+ id=self.ids.delete_button(self.aio_id),
239
+ ),
240
+ ],
241
+ grow=False,
242
+ gap="xs",
243
+ justify="right",
244
+ align="center",
245
+ ),
246
+ )
247
+
248
+ layout.extend(
249
+ [
250
+ html.Div(
251
+ [
252
+ dmc.Group(
253
+ self.generate_components(items_definition, self.aio_id, row_index=0),
254
+ grow=True,
255
+ gap="xs",
256
+ justify="center",
257
+ align="center",
258
+ ),
259
+ ],
260
+ id=self.ids.rows(self.aio_id),
261
+ style={
262
+ "display": "inline-block",
263
+ },
264
+ ),
265
+ dcc.Store(
266
+ id=self.ids._storage(self.aio_id),
267
+ data={
268
+ "aio_id": self.aio_id,
269
+ "enable_multiple_rows": enable_multiple_rows,
270
+ "number_of_rows": 1,
271
+ "items_definition": items_definition,
272
+ },
273
+ storage_type="memory",
274
+ ),
275
+ ],
276
+ )
277
+
278
+ super().__init__(layout)
279
+
280
+ @staticmethod
281
+ @callback(
282
+ Output(ids._storage(MATCH), "data", allow_duplicate=True),
283
+ Output(ids.rows(MATCH), "children", allow_duplicate=True),
284
+ Input(ids.add_button(MATCH), "n_clicks"),
285
+ State(ids.rows(MATCH), "children"),
286
+ State(ids._storage(MATCH), "data"),
287
+ )
288
+ def add_row(
289
+ clicked: int,
290
+ rows: list[dict[str, Any] | dmc.Group],
291
+ storage: dict[str, Any],
292
+ ) -> tuple[dict[str, Any], list[dict[str, Any] | dmc.Group]]:
293
+ """Add a new row to the array."""
294
+ if storage["enable_multiple_rows"] and clicked:
295
+ storage["number_of_rows"] += 1
296
+ aio_id = storage["aio_id"]
297
+ rows.append(
298
+ dmc.Group(
299
+ InputRowArray.generate_components(
300
+ storage["items_definition"],
301
+ aio_id,
302
+ row_index=storage["number_of_rows"] - 1,
303
+ ),
304
+ grow=True,
305
+ gap="xs",
306
+ justify="center",
307
+ align="center",
308
+ ),
309
+ )
310
+ return storage, rows
311
+ raise PreventUpdate
312
+
313
+ @staticmethod
314
+ @callback(
315
+ Output(ids._storage(MATCH), "data", allow_duplicate=True),
316
+ Output(ids.rows(MATCH), "children", allow_duplicate=True),
317
+ Input(ids.delete_button(MATCH), "n_clicks"),
318
+ State(ids.rows(MATCH), "children"),
319
+ State(ids._storage(MATCH), "data"),
320
+ )
321
+ def delete_row(
322
+ clicked: int,
323
+ rows: list[dict[str, Any]],
324
+ storage: dict[str, Any],
325
+ ) -> tuple[dict[str, Any], list[dict[str, Any]]]:
326
+ """Delete the last row from the array."""
327
+ if storage["enable_multiple_rows"] and clicked:
328
+ storage["number_of_rows"] -= 1
329
+ if len(rows) == 1:
330
+ return storage, []
331
+ elif len(rows) > 1:
332
+ del rows[-1]
333
+ return storage, rows
334
+ raise PreventUpdate
335
+
336
+ @classmethod
337
+ def generate_components(
338
+ cls, items_definition: list[dict[str, Any]], aio_id: str, row_index: int = 0
339
+ ) -> list[dmc.TextInput | dmc.NumberInput | dmc.Select]:
340
+ """Generate the components for the InputRowArray."""
341
+ components: list[dmc.TextInput | dmc.NumberInput | dmc.Select] = []
342
+ for item in items_definition:
343
+ component = cls._create_component(aio_id, row_index, item)
344
+ components.append(component)
345
+ return components
346
+
347
+ @classmethod
348
+ def _create_component(
349
+ cls, aio_id: str, row_index: int, item: dict[str, Any]
350
+ ) -> dmc.TextInput | dmc.NumberInput | dmc.Select:
351
+ if item["type"] == "TextInput":
352
+ component = dmc.TextInput(
353
+ id=cls.ids.input(aio_id, item["id"], row_index),
354
+ **{**default_text_input_props, **item["properties"]},
355
+ )
356
+ elif item["type"] == "NumberInput":
357
+ component = dmc.NumberInput(
358
+ id=cls.ids.input(aio_id, item["id"], row_index),
359
+ **{**default_number_input_props, **item["properties"]},
360
+ )
361
+ elif item["type"] == "Select":
362
+ component = dmc.Select(
363
+ id=cls.ids.input(aio_id, item["id"], row_index),
364
+ **{**default_select_props, **item["properties"]},
365
+ )
366
+ else:
367
+ raise ValueError(f"Unsupported item type: {item['type']}")
368
+ return component