supervisely 6.73.374__py3-none-any.whl → 6.73.376__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 (31) hide show
  1. supervisely/api/nn/neural_network_api.py +1 -1
  2. supervisely/app/widgets/__init__.py +1 -0
  3. supervisely/app/widgets/agent_selector/agent_selector.py +6 -0
  4. supervisely/app/widgets/agent_selector/template.html +2 -0
  5. supervisely/app/widgets/button/button.py +28 -1
  6. supervisely/app/widgets/button/template.html +1 -1
  7. supervisely/app/widgets/card/card.py +4 -0
  8. supervisely/app/widgets/card/template.html +1 -1
  9. supervisely/app/widgets/classes_table/classes_table.py +3 -1
  10. supervisely/app/widgets/fast_table/fast_table.py +16 -0
  11. supervisely/app/widgets/fast_table/script.js +6 -2
  12. supervisely/app/widgets/fast_table/template.html +1 -0
  13. supervisely/app/widgets/random_splits_table/random_splits_table.py +2 -0
  14. supervisely/app/widgets/select_collection/__init__.py +0 -0
  15. supervisely/app/widgets/select_collection/select_collection.py +693 -0
  16. supervisely/app/widgets/select_collection/template.html +3 -0
  17. supervisely/app/widgets/train_val_splits/train_val_splits.py +111 -13
  18. supervisely/nn/training/gui/gui.py +28 -1
  19. supervisely/nn/training/gui/train_val_splits_selector.py +133 -30
  20. supervisely/nn/training/train_app.py +44 -16
  21. supervisely/project/pointcloud_episode_project.py +16 -0
  22. supervisely/project/pointcloud_project.py +16 -0
  23. supervisely/project/project.py +57 -0
  24. supervisely/project/video_project.py +16 -0
  25. supervisely/project/volume_project.py +16 -0
  26. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/METADATA +1 -1
  27. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/RECORD +31 -28
  28. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/LICENSE +0 -0
  29. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/WHEEL +0 -0
  30. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/entry_points.txt +0 -0
  31. {supervisely-6.73.374.dist-info → supervisely-6.73.376.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,693 @@
1
+ from typing import Callable, Dict, List, Optional, Union
2
+
3
+ import supervisely.io.env as env
4
+ from supervisely.api.api import Api
5
+ from supervisely.app.widgets import Widget
6
+ from supervisely.app.widgets.checkbox.checkbox import Checkbox
7
+ from supervisely.app.widgets.container.container import Container
8
+ from supervisely.app.widgets.select.select import Select
9
+ from supervisely.app.widgets.tree_select.tree_select import TreeSelect
10
+ from supervisely.project.project_type import ProjectType
11
+
12
+
13
+ class SelectCollection(Widget):
14
+ """SelectCollection widget in Supervisely is a widget that allows users to select one or multiple collections (entities collections).
15
+ Read about it in `Developer Portal <https://developer.supervisely.com/app-development/widgets/selection/selectCollection>`_
16
+ (including screenshots and examples).
17
+
18
+ :param default_id: The ID of the collection to be selected by default.
19
+ :type default_id: Union[int, None]
20
+ :param project_id: The ID of the project to read collections from.
21
+ :type project_id: Union[int, None]
22
+ :param multiselect: Whether multiple collections can be selected.
23
+ :type multiselect: bool
24
+ :param compact: Whether the widget should be compact (e.g. no team, workspace, and project selectors).
25
+ :type compact: bool
26
+ :param select_all_collections: Whether all collections should be selected by default.
27
+ :type select_all_collections: bool
28
+ :param allowed_project_types: The list of project types that are allowed to be selected.
29
+ :type allowed_project_types: Optional[List[ProjectType]]
30
+ :param team_is_selectable: Whether the team selector should be selectable.
31
+ :type team_is_selectable: bool
32
+ :param workspace_is_selectable: Whether the workspace selector should be selectable.
33
+ :type workspace_is_selectable: bool
34
+ :param widget_id: The unique identifier of the widget.
35
+ :type widget_id: Union[str, None]
36
+ :param show_select_all_collections_checkbox: Whether the checkbox to select all collections should be shown.
37
+ :type show_select_all_collections_checkbox: bool
38
+
39
+ :Public methods:
40
+ - `set_project_id(project_id: int) -> None`: Set the project ID to read collections from.
41
+ - `get_selected_ids() -> Optional[List[int]]`: Get the IDs of the selected collections.
42
+ - `get_selected_id() -> Optional[int]`: Get the ID of the selected collection.
43
+ - `value_changed(func: Callable) -> Callable`: Decorator to set the callback function for the value changed event.
44
+ - `set_collection_id(collection_id: int) -> None`: Set the ID of the collection to be selected by default.
45
+ - `set_collection_ids(collection_ids: List[int]) -> None`: Set the IDs of the collections to be selected by default.
46
+ - `get_selected_project_id() -> Optional[int]`: Get the ID of the selected project.
47
+ - `get_selected_team_id() -> int`: Get the ID of the selected team.
48
+ - `set_team_id(team_id: int) -> None`: Set the team ID to read workspaces from.
49
+ - `get_selected_workspace_id() -> int`: Get the ID of the selected workspace.
50
+ - `set_workspace_id(workspace_id: int) -> None`: Set the workspace ID to read projects from.
51
+ - `is_all_selected() -> bool`: Check if all collections are selected.
52
+ - `select_all() -> None`: Select all collections.
53
+ - `disable() -> None`: Disable the widget in the UI.
54
+ - `enable() -> None`: Enable the widget in the UI.
55
+ - `set_selected_id(collection_id: int) -> None`: Set the ID of the collection to be selected by default.
56
+ - `set_selected_ids(collection_ids: List[int]) -> None`: Set the IDs of the collections to be selected by default.
57
+
58
+ :Properties:
59
+ - `team_id`: The ID of the team selected in the widget.
60
+ - `workspace_id`: The ID of the workspace selected in the widget.
61
+ - `project_id`: The ID of the project selected in the widget.
62
+
63
+ :Usage example:
64
+
65
+ .. code-block:: python
66
+ from supervisely.app.widgets import SelectCollection
67
+
68
+ project_id = 123
69
+ collection_id = 456
70
+
71
+ select_collection = SelectCollection(
72
+ default_id=collection_id,
73
+ project_id=project_id,
74
+ multiselect=True,
75
+ )
76
+
77
+ @select_collection.value_changed
78
+ def on_change(selected_ids):
79
+ print(selected_ids) # Output: [456, 789]
80
+ """
81
+
82
+ def __init__(
83
+ self,
84
+ default_id: Union[int, None] = None,
85
+ project_id: Union[int, None] = None,
86
+ multiselect: bool = False,
87
+ compact: bool = False,
88
+ select_all_collections: bool = False,
89
+ allowed_project_types: Optional[List[ProjectType]] = None,
90
+ team_is_selectable: bool = True,
91
+ workspace_is_selectable: bool = True,
92
+ show_select_all_collections_checkbox: bool = True,
93
+ widget_id: Union[str, None] = None,
94
+ width: int = 193,
95
+ ):
96
+ self._api = Api.from_env()
97
+
98
+ if default_id is not None and project_id is None:
99
+ raise ValueError("Project ID must be provided when default collection ID is set.")
100
+
101
+ if not multiselect and select_all_collections:
102
+ raise ValueError("Select all collections is only available in multiselect mode.")
103
+
104
+ # Reading team_id and workspace_id from environment variables.
105
+ # If not found, error will be raised.
106
+ self._team_id = env.team_id()
107
+ self._workspace_id = env.workspace_id()
108
+
109
+ # Using environment variables to set the default values if they are not provided.
110
+ self._project_id = project_id or env.project_id(raise_not_found=False)
111
+ self._collection_id = default_id
112
+
113
+ # Get mapping of collection ID to name for current project.
114
+ self._collections_names_map = None
115
+ self._collections_ids_map = None
116
+
117
+ self._multiselect = multiselect
118
+ self._compact = compact
119
+
120
+ # Extract values from Enum to match the .type property of the ProjectInfo object.
121
+
122
+ self._project_types = None
123
+ if allowed_project_types is not None:
124
+ if all(allowed_project_types) is isinstance(allowed_project_types, ProjectType):
125
+ self._project_types = (
126
+ [project_type.value for project_type in allowed_project_types]
127
+ if allowed_project_types is not None
128
+ else None
129
+ )
130
+ elif all(allowed_project_types) is isinstance(allowed_project_types, str):
131
+ self._project_types = allowed_project_types
132
+
133
+ # Widget components.
134
+ self._select_team = None
135
+ self._select_workspace = None
136
+ self._select_project = None
137
+ self._select_collection = None
138
+ self._select_all_collections_checkbox = None
139
+ self._width = width
140
+
141
+ # List of widgets will be used to create a Container.
142
+ self._widgets = []
143
+
144
+ if not compact:
145
+ # If the widget is not compact, create team, workspace, and project selectors.
146
+ self._create_selectors(team_is_selectable, workspace_is_selectable)
147
+
148
+ # Create the collection selector.
149
+ self._create_collection_selector(select_all_collections)
150
+
151
+ # Create the checkbox to select all collections if needed.
152
+ if show_select_all_collections_checkbox:
153
+ self._create_select_all_collections_checkbox(select_all_collections)
154
+
155
+ # Group the selectors and the collection selector into a container.
156
+ self._content = Container(self._widgets)
157
+ super().__init__(widget_id=widget_id, file_path=__file__)
158
+
159
+ def disable(self):
160
+ """Disable the widget in the UI."""
161
+ for widget in self._widgets:
162
+ widget.disable()
163
+
164
+ def enable(self) -> None:
165
+ """Enable the widget in the UI."""
166
+ for widget in self._widgets:
167
+ widget.enable()
168
+
169
+ @property
170
+ def team_id(self) -> int:
171
+ """The ID of the team selected in the widget.
172
+
173
+ :return: The ID of the team.
174
+ :rtype: int
175
+ """
176
+ return self._team_id
177
+
178
+ @team_id.setter
179
+ def team_id(self, team_id: int) -> None:
180
+ """Set the team ID to read workspaces from.
181
+
182
+ :param team_id: The ID of the team.
183
+ :type team_id: int
184
+ """
185
+ if not self._compact:
186
+ self._select_team.set_value(team_id)
187
+ self._select_workspace.set(self._get_select_items(team_id=team_id))
188
+ self._team_id = team_id
189
+
190
+ def get_selected_team_id(self) -> int:
191
+ """Get the ID of the selected team.
192
+
193
+ :return: The ID of the selected team.
194
+ :rtype: int
195
+ """
196
+ return self.team_id
197
+
198
+ def set_team_id(self, team_id: int) -> None:
199
+ """Set the team ID to read workspaces from.
200
+
201
+ :param team_id: The ID of the team.
202
+ :type team_id: int
203
+ """
204
+ self.team_id = team_id
205
+
206
+ @property
207
+ def workspace_id(self) -> int:
208
+ """The ID of the workspace selected in the widget.
209
+
210
+ :return: The ID of the workspace.
211
+ :rtype: int
212
+ """
213
+ return self._workspace_id
214
+
215
+ @workspace_id.setter
216
+ def workspace_id(self, workspace_id: int) -> None:
217
+ """Set the workspace ID to read projects from.
218
+
219
+ :param workspace_id: The ID of the workspace.
220
+ :type workspace_id: int
221
+ """
222
+ if not self._compact:
223
+ self._select_workspace.set_value(workspace_id)
224
+ self._select_project.set(self._get_select_items(workspace_id=workspace_id))
225
+ self._workspace_id = workspace_id
226
+
227
+ def get_selected_workspace_id(self) -> int:
228
+ """Get the ID of the selected workspace.
229
+
230
+ :return: The ID of the selected workspace.
231
+ :rtype: int
232
+ """
233
+ return self.workspace_id
234
+
235
+ def set_workspace_id(self, workspace_id: int) -> None:
236
+ """Set the workspace ID to read projects from.
237
+
238
+ :param workspace_id: The ID of the workspace.
239
+ :type workspace_id: int
240
+ """
241
+ self.workspace_id = workspace_id
242
+
243
+ @property
244
+ def project_id(self) -> Optional[int]:
245
+ """The ID of the project selected in the widget.
246
+
247
+ :return: The ID of the project.
248
+ :rtype: Optional[int]
249
+ """
250
+ return self._project_id
251
+
252
+ @project_id.setter
253
+ def project_id(self, project_id: Optional[int]) -> None:
254
+ """Set the project ID to read collections from.
255
+
256
+ :param project_id: The ID of the project.
257
+ :type project_id: int
258
+ """
259
+ if not self._compact:
260
+ self._select_project.set_value(project_id)
261
+ self.set_project_id(project_id)
262
+
263
+ def get_selected_project_id(self) -> Optional[int]:
264
+ """Get the ID of the selected project.
265
+
266
+ :return: The ID of the selected project.
267
+ :rtype: Optional[int]
268
+ """
269
+ return self.project_id
270
+
271
+ def set_collection(self, collection: Union[int, str]) -> None:
272
+ """Set the collection to be selected.
273
+
274
+ :param collection: The ID or name of the collection.
275
+ :type collection: The ID or name of the collection.
276
+ :raise ValueError: If multiselect is enabled.
277
+ """
278
+ if isinstance(collection, int):
279
+ self.set_selected_id(collection)
280
+ elif isinstance(collection, str):
281
+ self.set_selected_name(collection)
282
+ else:
283
+ raise ValueError("Collection ID must be an integer or a string.")
284
+
285
+ def set_collections(self, collections: Union[List[int], List[str]]) -> None:
286
+ """Set the collections to be selected.
287
+
288
+ :param collection: The ID or name of the collection.
289
+ :type collection: The ID or name of the collection.
290
+ :raise ValueError: If multiselect is disabled.
291
+ """
292
+ if not isinstance(collections, list):
293
+ raise ValueError("Collections must be a list of integers or strings.")
294
+ if all(isinstance(i, int) for i in collections) or len(collections) == 0:
295
+ self.set_selected_ids(collections)
296
+ elif all(isinstance(i, str) for i in collections):
297
+ self.set_selected_names(collections)
298
+ else:
299
+ raise ValueError("Collection IDs must be a list of integers or a list of strings.")
300
+
301
+ def value_changed(self, func: Callable) -> Callable:
302
+ """Decorator to set the callback function for the value changed event.
303
+
304
+ :param func: The callback function.
305
+ :type func: Callable
306
+ :return: The callback function.
307
+ :rtype: Callable
308
+ """
309
+
310
+ @self._select_collection.value_changed
311
+ def _click(items: Union[List[str], str]):
312
+ if isinstance(items, list):
313
+ res = [self._collections_names_map[item].id for item in items]
314
+ else:
315
+ res = self._collections_names_map[items].id
316
+
317
+ func(res)
318
+
319
+ return _click
320
+
321
+ def _create_select_all_collections_checkbox(self, select_all_collections: bool) -> None:
322
+ """Create the checkbox to select all collections.
323
+
324
+ :param select_all_collections: Whether all collections should be selected by default.
325
+ :type select_all_collections: bool
326
+ """
327
+ if not self._multiselect:
328
+ # We'll only create the checkbox if multiselect is enabled.
329
+ return
330
+ select_all_collections_checkbox = Checkbox("Select all collections")
331
+
332
+ @select_all_collections_checkbox.value_changed
333
+ def select_all_collections_checkbox_handler(checked: bool) -> None:
334
+ """Handler function for the event when the checkbox value changes.
335
+
336
+ :param checked: The value of the checkbox.
337
+ :type checked: bool
338
+ """
339
+ if self._project_id is None:
340
+ return
341
+
342
+ if checked:
343
+ self.select_all()
344
+ else:
345
+ self.deselect_all()
346
+
347
+ self._widgets.append(select_all_collections_checkbox)
348
+ self._select_all_collections_checkbox = select_all_collections_checkbox
349
+ if select_all_collections:
350
+ self.select_all()
351
+
352
+ def _create_collection_selector(self, select_all_collections: bool) -> None:
353
+ """Create the collection selector.
354
+
355
+ :param select_all_collections: Whether all collections should be selected by default.
356
+ :type select_all_collections: bool
357
+ """
358
+ items = self._read_collections(self._project_id)
359
+ if items is None or len(items) == 0:
360
+ items = []
361
+ self._select_collection = Select(
362
+ items=items,
363
+ multiple=self._multiselect,
364
+ width_px=self._width,
365
+ placeholder="Select collection",
366
+ filterable=True,
367
+ )
368
+ if self._collection_id is not None:
369
+ info = self._collections_ids_map.get(self._collection_id)
370
+ if info is not None:
371
+ value = [info.name] if self._multiselect else info.name
372
+ self._select_collection.set_value(value)
373
+ if select_all_collections:
374
+ self.select_all()
375
+
376
+ # Adding the collection selector to the list of widgets to be added to the container.
377
+ self._widgets.append(self._select_collection)
378
+
379
+ def _create_selectors(self, team_is_selectable: bool, workspace_is_selectable: bool):
380
+ """Create the team, workspace, and project selectors.
381
+
382
+ :param team_is_selectable: Whether the team selector should be selectable.
383
+ :type team_is_selectable: bool
384
+ :param workspace_is_selectable: Whether the workspace selector should be selectable.
385
+ :type workspace_is_selectable: bool
386
+ """
387
+
388
+ def team_selector_handler(team_id: int):
389
+ """Handler function for the event when the team selector value changes.
390
+
391
+ :param team_id: The ID of the selected team.
392
+ :type team_id: int
393
+ """
394
+ self._select_workspace.set(items=self._get_select_items(team_id=team_id))
395
+ self._team_id = team_id
396
+
397
+ def workspace_selector_handler(workspace_id: int):
398
+ """Handler function for the event when the workspace selector value changes.
399
+
400
+ :param workspace_id: The ID of the selected workspace.
401
+ :type workspace_id: int
402
+ """
403
+ self._select_project.set(items=self._get_select_items(workspace_id=workspace_id))
404
+ self._workspace_id = workspace_id
405
+
406
+ def project_selector_handler(project_id: int):
407
+ """Handler function for the event when the project selector value changes.
408
+
409
+ :param project_id: The ID of the selected project.
410
+ :type project_id: int
411
+ """
412
+ self._select_collection.set(self._read_collections(project_id))
413
+ self._project_id = project_id
414
+
415
+ if (
416
+ self._select_all_collections_checkbox is not None
417
+ and self._select_all_collections_checkbox.is_checked()
418
+ ):
419
+ self.select_all()
420
+ self._select_collection.hide()
421
+
422
+ self._select_team = Select(
423
+ items=self._get_select_items(),
424
+ placeholder="Select team",
425
+ filterable=True,
426
+ width_px=self._width,
427
+ )
428
+ self._select_team.set_value(self._team_id)
429
+ if not team_is_selectable:
430
+ self._select_team.disable()
431
+
432
+ self._select_workspace = Select(
433
+ items=self._get_select_items(team_id=self._team_id),
434
+ placeholder="Select workspace",
435
+ filterable=True,
436
+ width_px=self._width,
437
+ )
438
+ self._select_workspace.set_value(self._workspace_id)
439
+ if not workspace_is_selectable:
440
+ self._select_workspace.disable()
441
+
442
+ self._select_project = Select(
443
+ items=self._get_select_items(workspace_id=self._workspace_id),
444
+ placeholder="Select project",
445
+ filterable=True,
446
+ width_px=self._width,
447
+ )
448
+ self._select_project.set_value(self._project_id)
449
+
450
+ # Register the event handlers.
451
+ self._select_team.value_changed(team_selector_handler)
452
+ self._select_workspace.value_changed(workspace_selector_handler)
453
+ self._select_project.value_changed(project_selector_handler)
454
+
455
+ # Adding widgets to the list, so they can be added to the container.
456
+ self._widgets.extend([self._select_team, self._select_workspace, self._select_project])
457
+
458
+ def _get_select_items(self, **kwargs) -> List[Select.Item]:
459
+ """Get the list of items for the team, workspace, and project selectors.
460
+ Possible keyword arguments are 'team_id' and 'workspace_id'.
461
+
462
+ :return: The list of items.
463
+ :rtype: List[Select.Item]
464
+ """
465
+ if not kwargs:
466
+ items = self._api.team.get_list()
467
+ elif "team_id" in kwargs:
468
+ items = self._api.workspace.get_list(kwargs["team_id"])
469
+ elif "workspace_id" in kwargs:
470
+ projects_list = self._api.project.get_list(kwargs["workspace_id"])
471
+ if self._project_types is not None:
472
+ items = [
473
+ project for project in projects_list if project.type in self._project_types
474
+ ] # TODO: Filter project from API, not from here.
475
+ else:
476
+ items = projects_list
477
+
478
+ return [Select.Item(value=item.id, label=item.name) for item in items]
479
+
480
+ def get_json_data(self) -> Dict:
481
+ """Get the JSON data of the widget.
482
+
483
+ :return: The JSON data.
484
+ :rtype: Dict
485
+ """
486
+ return {}
487
+
488
+ def get_json_state(self) -> Dict:
489
+ """Get the JSON state of the widget.
490
+
491
+ :return: The JSON state.
492
+ :rtype: Dict
493
+ """
494
+ return {}
495
+
496
+ def _read_collections(self, project_id: Optional[int]) -> Optional[List[Select.Item]]:
497
+ """Get the lisf of Select.Item objects representing the collection hierarchy.
498
+
499
+ :param project_id: The ID of the project.
500
+ :type project_id: Optional[int]
501
+ :return: The list of Select.Item objects.
502
+ :rtype: Optional[List[Select.Item]]
503
+ """
504
+ self._fetch_collections(project_id)
505
+
506
+ if not self._collections_names_map or not project_id:
507
+ return None
508
+
509
+ collections = [Select.Item(i.name, i.name) for i in self._collections_names_map.values()]
510
+ return collections
511
+
512
+ def _fetch_collections(self, project_id: Optional[int]) -> None:
513
+ """Get the mapping of collection name to EntitiesCollectionInfo object.
514
+
515
+ :param project_id: The ID of the project.
516
+ :type project_id: Optional[int]
517
+ :return: None
518
+ :rtype: None
519
+ """
520
+ self._collections_names_map = {}
521
+ self._collections_ids_map = {}
522
+
523
+ if not project_id:
524
+ return
525
+
526
+ for collection in self._api.entities_collection.get_list(project_id):
527
+ self._collections_names_map[collection.name] = collection
528
+ self._collections_ids_map[collection.id] = collection
529
+
530
+ def set_project_id(self, project_id: Optional[int]) -> None:
531
+ """Set the project ID to read collections from.
532
+
533
+ :param project_id: The ID of the project.
534
+ :type project_id: int
535
+ """
536
+ self._project_id = project_id
537
+ items = self._read_collections(project_id)
538
+ if items is None or len(items) == 0:
539
+ self._select_collection.set([])
540
+ return
541
+ self._select_collection.set(items)
542
+ if self._multiselect:
543
+ if self._select_all_collections_checkbox.is_checked():
544
+ self.select_all()
545
+ else:
546
+ self.deselect_all()
547
+ else:
548
+ self._select_collection.set_value("")
549
+
550
+ def _get_selected(self) -> Optional[Union[List[int], int]]:
551
+ """Get the ID of the selected collection(s).
552
+
553
+ :return: The ID of the selected collection(s).
554
+ :rtype: Optional[Union[List[int], int]]
555
+ """
556
+ selected = self._select_collection.get_value()
557
+ if not selected:
558
+ return None
559
+
560
+ if isinstance(selected, list):
561
+ return [self._collections_names_map[item].id for item in selected]
562
+ else:
563
+ return self._collections_names_map[selected].id
564
+
565
+ def get_selected_ids(self) -> Optional[List[int]]:
566
+ """Get the IDs of the selected collections.
567
+
568
+ raise ValueError if multiselect is disabled.
569
+ return: The IDs of the selected collections.
570
+ rtype: Optional[List[int]]
571
+ """
572
+ if not self._multiselect:
573
+ raise ValueError("This method can only be called when multiselect is enabled.")
574
+ return self._get_selected()
575
+
576
+ def get_selected_id(self) -> Optional[int]:
577
+ """Get the ID of the selected collection.
578
+
579
+ raise ValueError if multiselect is enabled.
580
+ return: The ID of the selected collection.
581
+ rtype: Optional[int]
582
+ """
583
+ if self._multiselect:
584
+ raise ValueError("This method can only be called when multiselect is disabled.")
585
+ return self._get_selected()
586
+
587
+ def set_selected_ids(self, collection_ids: List[int]) -> None:
588
+ """Set the IDs of the collections to be selected by default.
589
+
590
+ :param collection_ids: The IDs of the collections.
591
+ :type collection_ids: List[int]
592
+ """
593
+ if not self._multiselect:
594
+ raise ValueError("This method can only be called when multiselect is enabled.")
595
+ self._set_selected_by_ids(collection_ids)
596
+
597
+ def set_selected_id(self, collection_id: int) -> None:
598
+ """Set the ID of the collection to be selected by default.
599
+
600
+ :param collection_id: The ID of the collection.
601
+ :type collection_id: int
602
+ """
603
+ if self._multiselect:
604
+ raise ValueError("This method can only be called when multiselect is disabled.")
605
+ self._set_selected_by_ids([collection_id])
606
+
607
+ def _set_selected_by_ids(self, collection_ids: List[int]) -> None:
608
+ """Set the IDs of the collections to be selected by default.
609
+
610
+ :param collection_ids: The IDs of the collections.
611
+ :type collection_ids: List[int]
612
+ """
613
+ if not self._collections_ids_map:
614
+ return
615
+
616
+ selected = []
617
+ for i in collection_ids:
618
+ if i in self._collections_ids_map:
619
+ selected.append(self._collections_ids_map[i].name)
620
+
621
+ if self._multiselect:
622
+ if len(selected) == len(self._collections_ids_map):
623
+ self.select_all()
624
+ else:
625
+ self.deselect_all()
626
+ self._select_collection.set_value(selected)
627
+
628
+ else:
629
+ if len(selected) > 1:
630
+ raise ValueError("More than one collection found, but multiselect is disabled.")
631
+ value = selected[0] if selected else ""
632
+ self._select_collection.set_value(value)
633
+
634
+ def set_selected_name(self, collection_name: str) -> None:
635
+ """Set the name of the collection to be selected by default.
636
+
637
+ :param collection_name: The name of the collection.
638
+ :type collection_name: str
639
+ """
640
+ if self._multiselect:
641
+ raise ValueError("This method can only be called when multiselect is disabled.")
642
+ self._set_selected_by_names([collection_name])
643
+
644
+ def set_selected_names(self, collection_names: List[str]) -> None:
645
+ """Set the names of the collections to be selected by default.
646
+
647
+ :param collection_names: The names of the collections.
648
+ :type collection_names: List[str]
649
+ """
650
+ if not self._multiselect:
651
+ raise ValueError("This method can only be called when multiselect is enabled.")
652
+ self._set_selected_by_names(collection_names)
653
+
654
+ def _set_selected_by_names(self, collection_names: List[str]) -> None:
655
+ """Set the names of the collections to be selected by default.
656
+
657
+ :param collection_names: The names of the collections.
658
+ :type collection_names: List[str]
659
+ """
660
+ if not self._collections_names_map:
661
+ return
662
+
663
+ ids = []
664
+ for i in collection_names:
665
+ if i in self._collections_names_map:
666
+ ids.append(self._collections_names_map[i].id)
667
+ self._set_selected_by_ids(ids)
668
+
669
+ def is_all_selected(self) -> bool:
670
+ """Check if all collections are selected.
671
+
672
+ return: True if all collections are selected, False otherwise.
673
+ rtype: bool
674
+ """
675
+ return len(self._select_collection.get_value()) == len(self._collections_names_map)
676
+
677
+ def select_all(self) -> None:
678
+ """Select all collections."""
679
+ if not self._multiselect:
680
+ raise ValueError("This method can only be called when multiselect is enabled.")
681
+ self._select_collection.set_value(list(self._collections_names_map.keys()))
682
+ if self._select_all_collections_checkbox is not None:
683
+ self._select_all_collections_checkbox.check()
684
+ self._select_collection.hide()
685
+
686
+ def deselect_all(self) -> None:
687
+ """Deselect all collections."""
688
+ if not self._multiselect:
689
+ raise ValueError("This method can only be called when multiselect is enabled.")
690
+ self._select_collection.set_value([])
691
+ if self._select_all_collections_checkbox is not None:
692
+ self._select_all_collections_checkbox.uncheck()
693
+ self._select_collection.show()
@@ -0,0 +1,3 @@
1
+ <div>
2
+ {{{widget._content}}}
3
+ </div>