cjm-transcript-source-select 0.0.7__tar.gz → 0.0.8__tar.gz
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.
- {cjm_transcript_source_select-0.0.7/cjm_transcript_source_select.egg-info → cjm_transcript_source_select-0.0.8}/PKG-INFO +232 -163
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/README.md +230 -162
- cjm_transcript_source_select-0.0.8/cjm_transcript_source_select/__init__.py +1 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/_modidx.py +30 -22
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/components/local_files.py +42 -65
- cjm_transcript_source_select-0.0.8/cjm_transcript_source_select/components/source_browser.py +408 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/components/step_renderer.py +160 -170
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/html_ids.py +7 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/models.py +1 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/routes/core.py +37 -39
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/routes/filtering.py +12 -33
- cjm_transcript_source_select-0.0.8/cjm_transcript_source_select/routes/init.py +123 -0
- cjm_transcript_source_select-0.0.8/cjm_transcript_source_select/routes/local_files.py +191 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/routes/queue.py +82 -17
- cjm_transcript_source_select-0.0.8/cjm_transcript_source_select/routes/source_browser.py +231 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/routes/tabs.py +25 -56
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8/cjm_transcript_source_select.egg-info}/PKG-INFO +232 -163
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select.egg-info/SOURCES.txt +1 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select.egg-info/requires.txt +1 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/settings.ini +2 -2
- cjm_transcript_source_select-0.0.7/cjm_transcript_source_select/__init__.py +0 -1
- cjm_transcript_source_select-0.0.7/cjm_transcript_source_select/components/source_browser.py +0 -367
- cjm_transcript_source_select-0.0.7/cjm_transcript_source_select/routes/init.py +0 -73
- cjm_transcript_source_select-0.0.7/cjm_transcript_source_select/routes/local_files.py +0 -232
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/LICENSE +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/MANIFEST.in +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/components/__init__.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/components/helpers.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/components/preview_panel.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/components/selection_queue.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/routes/__init__.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/services/__init__.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/services/source.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/services/source_utils.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select/utils.py +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select.egg-info/dependency_links.txt +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select.egg-info/entry_points.txt +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select.egg-info/not-zip-safe +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/cjm_transcript_source_select.egg-info/top_level.txt +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/pyproject.toml +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/setup.cfg +0 -0
- {cjm_transcript_source_select-0.0.7 → cjm_transcript_source_select-0.0.8}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: cjm-transcript-source-select
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.8
|
|
4
4
|
Summary: FastHTML source selection component for transcript decomposition workflows, with federated database browsing, drag-drop ordering, and keyboard navigation.
|
|
5
5
|
Home-page: https://github.com/cj-mills/cjm-transcript-source-select
|
|
6
6
|
Author: Christian J. Mills
|
|
@@ -28,6 +28,7 @@ Requires-Dist: cjm_workflow_state
|
|
|
28
28
|
Requires-Dist: cjm_source_provider
|
|
29
29
|
Requires-Dist: cjm_fasthtml_interactions
|
|
30
30
|
Requires-Dist: cjm_fasthtml_viewport_fit
|
|
31
|
+
Requires-Dist: cjm_fasthtml_virtual_collection
|
|
31
32
|
Provides-Extra: dev
|
|
32
33
|
Dynamic: author
|
|
33
34
|
Dynamic: author-email
|
|
@@ -63,13 +64,14 @@ pip install cjm_transcript_source_select
|
|
|
63
64
|
│ ├── selection_queue.ipynb # Selection queue component with drag-drop reordering
|
|
64
65
|
│ ├── source_browser.ipynb # Source browser components for displaying and filtering transcription sources
|
|
65
66
|
│ └── step_renderer.ipynb # Phase 1 step renderer: Source Selection & Ordering with two-column layout and collapsible preview
|
|
66
|
-
├── routes/ (
|
|
67
|
-
│ ├── core.ipynb
|
|
68
|
-
│ ├── filtering.ipynb
|
|
69
|
-
│ ├── init.ipynb
|
|
70
|
-
│ ├── local_files.ipynb
|
|
71
|
-
│ ├── queue.ipynb
|
|
72
|
-
│
|
|
67
|
+
├── routes/ (7)
|
|
68
|
+
│ ├── core.ipynb # Selection step state management helpers
|
|
69
|
+
│ ├── filtering.ipynb # Filtering, grouping, and keyboard navigation route handlers
|
|
70
|
+
│ ├── init.ipynb # Router assembly for Phase 1 selection routes
|
|
71
|
+
│ ├── local_files.ipynb # Local files browser route handlers
|
|
72
|
+
│ ├── queue.ipynb # Selection queue route handlers for Phase 1
|
|
73
|
+
│ ├── source_browser.ipynb # Source browser virtual collection router for Phase 1 selection
|
|
74
|
+
│ └── tabs.ipynb # Tab switching route handlers
|
|
73
75
|
├── services/ (2)
|
|
74
76
|
│ ├── source.ipynb # Source service for federated transcription queries via DuckDB
|
|
75
77
|
│ └── source_utils.ipynb # Source record operations for metadata extraction, grouping, and validation
|
|
@@ -77,7 +79,7 @@ pip install cjm_transcript_source_select
|
|
|
77
79
|
├── models.ipynb # Data models and URL bundles for Phase 1: Source Selection & Ordering
|
|
78
80
|
└── utils.ipynb # Display formatting and word counting utilities for the selection step
|
|
79
81
|
|
|
80
|
-
Total:
|
|
82
|
+
Total: 18 notebooks across 3 directories
|
|
81
83
|
|
|
82
84
|
## Module Dependencies
|
|
83
85
|
|
|
@@ -96,65 +98,69 @@ graph LR
|
|
|
96
98
|
routes_init[routes.init<br/>init]
|
|
97
99
|
routes_local_files[routes.local_files<br/>local_files]
|
|
98
100
|
routes_queue[routes.queue<br/>queue]
|
|
101
|
+
routes_source_browser[routes.source_browser<br/>source_browser]
|
|
99
102
|
routes_tabs[routes.tabs<br/>tabs]
|
|
100
103
|
services_source[services.source<br/>source]
|
|
101
104
|
services_source_utils[services.source_utils<br/>source_utils]
|
|
102
105
|
utils[utils<br/>utils]
|
|
103
106
|
|
|
104
107
|
components_helpers --> models
|
|
105
|
-
components_local_files --> components_helpers
|
|
106
108
|
components_local_files --> html_ids
|
|
109
|
+
components_local_files --> components_helpers
|
|
107
110
|
components_preview_panel --> html_ids
|
|
108
111
|
components_selection_queue --> html_ids
|
|
109
|
-
components_source_browser --> services_source_utils
|
|
110
112
|
components_source_browser --> utils
|
|
113
|
+
components_source_browser --> services_source_utils
|
|
111
114
|
components_source_browser --> html_ids
|
|
112
|
-
components_step_renderer --> models
|
|
113
|
-
components_step_renderer --> components_selection_queue
|
|
114
115
|
components_step_renderer --> components_local_files
|
|
115
|
-
components_step_renderer --> components_preview_panel
|
|
116
116
|
components_step_renderer --> components_helpers
|
|
117
117
|
components_step_renderer --> html_ids
|
|
118
118
|
components_step_renderer --> components_source_browser
|
|
119
|
+
components_step_renderer --> models
|
|
120
|
+
components_step_renderer --> components_selection_queue
|
|
121
|
+
components_step_renderer --> components_preview_panel
|
|
119
122
|
components_step_renderer --> utils
|
|
120
|
-
routes_core -->
|
|
121
|
-
routes_core -->
|
|
123
|
+
routes_core --> html_ids
|
|
124
|
+
routes_core --> models
|
|
122
125
|
routes_core --> components_step_renderer
|
|
126
|
+
routes_core --> components_selection_queue
|
|
123
127
|
routes_core --> services_source
|
|
124
|
-
|
|
125
|
-
routes_core --> html_ids
|
|
126
|
-
routes_filtering --> models
|
|
128
|
+
routes_filtering --> routes_core
|
|
127
129
|
routes_filtering --> services_source_utils
|
|
130
|
+
routes_filtering --> models
|
|
128
131
|
routes_filtering --> services_source
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
routes_init --> routes_queue
|
|
133
|
+
routes_init --> routes_local_files
|
|
131
134
|
routes_init --> routes_core
|
|
135
|
+
routes_init --> routes_tabs
|
|
136
|
+
routes_init --> routes_filtering
|
|
132
137
|
routes_init --> models
|
|
138
|
+
routes_init --> routes_source_browser
|
|
133
139
|
routes_init --> services_source
|
|
134
|
-
routes_init --> routes_queue
|
|
135
|
-
routes_init --> routes_filtering
|
|
136
|
-
routes_init --> routes_tabs
|
|
137
|
-
routes_init --> routes_local_files
|
|
138
140
|
routes_local_files --> components_local_files
|
|
139
|
-
routes_local_files --> services_source
|
|
140
141
|
routes_local_files --> routes_core
|
|
141
142
|
routes_local_files --> models
|
|
142
|
-
|
|
143
|
+
routes_local_files --> services_source
|
|
143
144
|
routes_queue --> services_source_utils
|
|
144
|
-
routes_queue -->
|
|
145
|
+
routes_queue --> routes_core
|
|
145
146
|
routes_queue --> models
|
|
147
|
+
routes_queue --> components_preview_panel
|
|
146
148
|
routes_queue --> services_source
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
routes_source_browser --> components_source_browser
|
|
150
|
+
routes_source_browser --> html_ids
|
|
151
|
+
routes_source_browser --> models
|
|
152
|
+
routes_source_browser --> services_source_utils
|
|
153
|
+
routes_source_browser --> components_preview_panel
|
|
154
|
+
routes_source_browser --> routes_core
|
|
155
|
+
routes_source_browser --> services_source
|
|
156
|
+
routes_tabs --> services_source_utils
|
|
150
157
|
routes_tabs --> routes_core
|
|
158
|
+
routes_tabs --> components_step_renderer
|
|
151
159
|
routes_tabs --> models
|
|
152
|
-
routes_tabs --> components_source_browser
|
|
153
160
|
routes_tabs --> services_source
|
|
154
|
-
routes_tabs --> services_source_utils
|
|
155
161
|
```
|
|
156
162
|
|
|
157
|
-
*
|
|
163
|
+
*54 cross-module dependencies detected*
|
|
158
164
|
|
|
159
165
|
## CLI Reference
|
|
160
166
|
|
|
@@ -200,12 +206,10 @@ def _find_duplicate_media_source(
|
|
|
200
206
|
|
|
201
207
|
``` python
|
|
202
208
|
def _render_duplicate_flash(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
) -> Div: # OOB Div with flash script (replaces previous via innerHTML swap)
|
|
208
|
-
"Render a fixed-ID container with flash script for two source rows."
|
|
209
|
+
candidate_row_id: str, # DOM element ID of the candidate row
|
|
210
|
+
existing_row_id: Optional[str] = None, # DOM element ID of the conflicting row (None if off-screen)
|
|
211
|
+
) -> Div: # OOB Div with flash script
|
|
212
|
+
"Render a flash animation on one or two rows to indicate duplicate rejection."
|
|
209
213
|
```
|
|
210
214
|
|
|
211
215
|
``` python
|
|
@@ -226,8 +230,7 @@ def _build_queue_response(
|
|
|
226
230
|
selected_sources: List[Dict[str, str]], # Current selected sources after mutation
|
|
227
231
|
urls: SelectionUrls, # URL bundle for rendering
|
|
228
232
|
include_stats: bool = True, # Include OOB stats swap
|
|
229
|
-
|
|
230
|
-
grouping_mode: str = None, # Override grouping mode for source list rendering
|
|
233
|
+
include_checkbox_oobs: bool = True, # Include OOB checkbox cells for visible rows
|
|
231
234
|
) -> Union[Any, Tuple]: # Single component or tuple of components with OOB swaps
|
|
232
235
|
"Build the standard response for queue-mutating handlers."
|
|
233
236
|
```
|
|
@@ -241,6 +244,12 @@ def _update_step_state(
|
|
|
241
244
|
|
|
242
245
|
``` python
|
|
243
246
|
DEBUG_SELECTION_STATE = False
|
|
247
|
+
_rebuild_and_render_ref: list
|
|
248
|
+
_sync_items_ref: list
|
|
249
|
+
_get_checkbox_oobs_ref: list
|
|
250
|
+
_get_checkbox_oob_for_ref: list
|
|
251
|
+
_get_vc_row_id_for_ref: list
|
|
252
|
+
_activate_toggle_ref: list
|
|
244
253
|
```
|
|
245
254
|
|
|
246
255
|
### filtering (`filtering.ipynb`)
|
|
@@ -266,7 +275,7 @@ def _handle_source_filter(
|
|
|
266
275
|
sess, # FastHTML session object
|
|
267
276
|
search: str, # Search term from input
|
|
268
277
|
urls: SelectionUrls, # URL bundle for rendering
|
|
269
|
-
): #
|
|
278
|
+
): # VC content wrapper (direct swap, not OOB)
|
|
270
279
|
"Filter transcription sources by search term."
|
|
271
280
|
```
|
|
272
281
|
|
|
@@ -279,8 +288,8 @@ def _handle_grouping_change(
|
|
|
279
288
|
sess, # FastHTML session object
|
|
280
289
|
grouping_mode: str, # New grouping mode: "media_path" or "batch_id"
|
|
281
290
|
urls: SelectionUrls, # URL bundle for rendering
|
|
282
|
-
): #
|
|
283
|
-
"Change the grouping mode and re-render the
|
|
291
|
+
): # VC content wrapper (direct swap, not OOB)
|
|
292
|
+
"Change the grouping mode and re-render the VC content."
|
|
284
293
|
```
|
|
285
294
|
|
|
286
295
|
``` python
|
|
@@ -427,7 +436,7 @@ def init_selection_routers(
|
|
|
427
436
|
source_service: SourceService, # The source service for queries
|
|
428
437
|
workflow_id: str, # The workflow identifier
|
|
429
438
|
prefix: str, # Base prefix for selection routes (e.g., "/workflow/selection")
|
|
430
|
-
) -> Tuple[List[APIRouter], SelectionUrls, Dict[str, Callable]
|
|
439
|
+
) -> Tuple[List[APIRouter], SelectionUrls, Dict[str, Callable], Callable, "SourceBrowserRouterState"]
|
|
431
440
|
"Initialize and return all selection routers with URL bundle."
|
|
432
441
|
```
|
|
433
442
|
|
|
@@ -474,22 +483,24 @@ def _create_db_browser_config() -> FileBrowserConfig: # Configured FileBrowserC
|
|
|
474
483
|
def _render_external_sources_list(
|
|
475
484
|
external_paths: List[str], # List of added external database paths
|
|
476
485
|
remove_url: str, # URL for removing external source
|
|
477
|
-
|
|
486
|
+
oob: bool = False, # Whether to render as OOB swap
|
|
487
|
+
) -> Any: # External sources section component (always rendered for OOB targeting)
|
|
478
488
|
"Render the list of added external database sources with scrollable paths."
|
|
479
489
|
```
|
|
480
490
|
|
|
491
|
+
``` python
|
|
492
|
+
def _render_error_alert(
|
|
493
|
+
error_message: Optional[str] = None, # Error message to display (None = clear)
|
|
494
|
+
oob: bool = False, # Whether to render as OOB swap
|
|
495
|
+
) -> Any: # Error alert container (always present for OOB targeting)
|
|
496
|
+
"Render the error alert container for the local files browser."
|
|
497
|
+
```
|
|
498
|
+
|
|
481
499
|
``` python
|
|
482
500
|
def _render_local_files_browser(
|
|
483
|
-
|
|
501
|
+
render_fn: Optional[Callable] = None, # FileBrowserRouters.render callable
|
|
484
502
|
external_paths: Optional[List[str]] = None, # List of added external database paths
|
|
485
|
-
provider: Optional[LocalFileSystemProvider] = None, # File system provider
|
|
486
|
-
config: Optional[FileBrowserConfig] = None, # Browser configuration
|
|
487
|
-
navigate_url: str = "", # URL for browsing directories
|
|
488
|
-
select_url: str = "", # URL for adding external source (maps path to db_path)
|
|
489
503
|
remove_url: str = "", # URL for removing external source
|
|
490
|
-
refresh_url: str = "", # URL for refreshing browser
|
|
491
|
-
path_input_url: str = "", # URL for direct path input
|
|
492
|
-
home_path: Optional[str] = None, # Home directory path
|
|
493
504
|
error_message: Optional[str] = None, # Error message to display
|
|
494
505
|
) -> Any: # Local files browser component
|
|
495
506
|
"Render the local files browser for adding external .db files."
|
|
@@ -517,49 +528,17 @@ def _get_local_files_provider() -> LocalFileSystemProvider:
|
|
|
517
528
|
"Get or create the local files provider singleton."
|
|
518
529
|
```
|
|
519
530
|
|
|
520
|
-
``` python
|
|
521
|
-
def _handle_browse_directory(
|
|
522
|
-
state_store: WorkflowStateStore, # The workflow state store
|
|
523
|
-
workflow_id: str, # The workflow identifier
|
|
524
|
-
source_service: SourceService, # The source service for external db ops
|
|
525
|
-
request, # FastHTML request object
|
|
526
|
-
sess, # FastHTML session object
|
|
527
|
-
path: str, # Directory path to browse
|
|
528
|
-
urls: SelectionUrls, # URL bundle for rendering
|
|
529
|
-
): # Local files browser component
|
|
530
|
-
"Browse a directory and return the local files browser component."
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
``` python
|
|
534
|
-
def _get_local_files_config() -> FileBrowserConfig:
|
|
535
|
-
"""Get or create the local files config singleton."""
|
|
536
|
-
global _local_files_config
|
|
537
|
-
if _local_files_config is None
|
|
538
|
-
"Get or create the local files config singleton."
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
``` python
|
|
542
|
-
def _handle_add_external_source(
|
|
543
|
-
state_store: WorkflowStateStore, # The workflow state store
|
|
544
|
-
workflow_id: str, # The workflow identifier
|
|
545
|
-
source_service: SourceService, # The source service for external db ops
|
|
546
|
-
request, # FastHTML request object
|
|
547
|
-
sess, # FastHTML session object
|
|
548
|
-
path: str, # Path to the .db file (from file-browser select_url)
|
|
549
|
-
urls: SelectionUrls, # URL bundle for rendering
|
|
550
|
-
): # Local files browser component
|
|
551
|
-
"Toggle an external database source (add if not present, remove if present)."
|
|
552
|
-
```
|
|
553
|
-
|
|
554
531
|
``` python
|
|
555
532
|
def _handle_remove_external_source(
|
|
556
533
|
state_store: WorkflowStateStore, # The workflow state store
|
|
557
534
|
workflow_id: str, # The workflow identifier
|
|
558
535
|
source_service: SourceService, # The source service for external db ops
|
|
559
|
-
request, # FastHTML request object
|
|
560
536
|
sess, # FastHTML session object
|
|
561
537
|
db_path: str, # Path to the .db file to remove
|
|
562
|
-
|
|
538
|
+
external_db_paths_ref: List[str], # Shared external paths list (mutated in place)
|
|
539
|
+
fb_state_getter: Callable[[], BrowserState], # File browser state getter
|
|
540
|
+
fb_state_setter: Callable[[BrowserState], None], # File browser state setter
|
|
541
|
+
render_panel_fn: Callable, # Function to render the full local files panel
|
|
563
542
|
): # Local files browser component
|
|
564
543
|
"Remove an external database source from the Added Sources list."
|
|
565
544
|
```
|
|
@@ -571,15 +550,14 @@ def init_local_files_router(
|
|
|
571
550
|
source_service: SourceService, # The source service for external db ops
|
|
572
551
|
prefix: str, # Route prefix (e.g., "/workflow/selection/local_files")
|
|
573
552
|
urls: SelectionUrls, # URL bundle for rendering
|
|
574
|
-
) -> Tuple[
|
|
575
|
-
"Initialize local files browser routes."
|
|
553
|
+
) -> Tuple[List, Dict[str, Callable], Callable]: # (routers, route_dict, render_panel_fn)
|
|
554
|
+
"Initialize local files browser routes with new file browser API."
|
|
576
555
|
```
|
|
577
556
|
|
|
578
557
|
#### Variables
|
|
579
558
|
|
|
580
559
|
``` python
|
|
581
560
|
_local_files_provider: Optional[LocalFileSystemProvider] = None
|
|
582
|
-
_local_files_config: Optional[FileBrowserConfig] = None
|
|
583
561
|
```
|
|
584
562
|
|
|
585
563
|
### models (`models.ipynb`)
|
|
@@ -609,6 +587,7 @@ class SelectionUrls:
|
|
|
609
587
|
|
|
610
588
|
add: str = '' # Add source to queue
|
|
611
589
|
remove: str = '' # Remove source from queue
|
|
590
|
+
toggle: str = '' # Toggle source selection (add/remove based on current state)
|
|
612
591
|
reorder: str = '' # Reorder queue items
|
|
613
592
|
clear: str = '' # Clear all from queue
|
|
614
593
|
select_all: str = '' # Select all in a group
|
|
@@ -658,6 +637,20 @@ from cjm_transcript_source_select.routes.queue import (
|
|
|
658
637
|
|
|
659
638
|
#### Functions
|
|
660
639
|
|
|
640
|
+
``` python
|
|
641
|
+
def _handle_selection_toggle(
|
|
642
|
+
state_store: WorkflowStateStore, # The workflow state store
|
|
643
|
+
workflow_id: str, # The workflow identifier
|
|
644
|
+
source_service: SourceService, # The source service for queries
|
|
645
|
+
request, # FastHTML request object
|
|
646
|
+
sess, # FastHTML session object
|
|
647
|
+
record_id: str, # Job ID to toggle
|
|
648
|
+
provider_id: str, # Plugin name for the source
|
|
649
|
+
urls: SelectionUrls, # URL bundle for rendering
|
|
650
|
+
): # Queue component with OOB stats (no checkbox OOBs -- checkbox already correct)
|
|
651
|
+
"Toggle a source's selection state (add if absent, remove if present)."
|
|
652
|
+
```
|
|
653
|
+
|
|
661
654
|
``` python
|
|
662
655
|
def _handle_selection_add(
|
|
663
656
|
state_store: WorkflowStateStore, # The workflow state store
|
|
@@ -668,7 +661,7 @@ def _handle_selection_add(
|
|
|
668
661
|
record_id: str, # Job ID to add
|
|
669
662
|
provider_id: str, # Plugin name for the source
|
|
670
663
|
urls: SelectionUrls, # URL bundle for rendering
|
|
671
|
-
): # Queue component with OOB stats
|
|
664
|
+
): # Queue component with OOB stats and visible checkbox OOBs
|
|
672
665
|
"Add a source to the selection queue."
|
|
673
666
|
```
|
|
674
667
|
|
|
@@ -682,7 +675,7 @@ def _handle_selection_remove(
|
|
|
682
675
|
record_id: str, # Job ID to remove
|
|
683
676
|
provider_id: str, # Plugin name for the source
|
|
684
677
|
urls: SelectionUrls, # URL bundle for rendering
|
|
685
|
-
): # Queue component with OOB stats
|
|
678
|
+
): # Queue component with OOB stats and visible checkbox OOBs
|
|
686
679
|
"Remove a source from the selection queue."
|
|
687
680
|
```
|
|
688
681
|
|
|
@@ -1023,7 +1016,15 @@ VALID_DB_EXTENSIONS = [3 items]
|
|
|
1023
1016
|
#### Import
|
|
1024
1017
|
|
|
1025
1018
|
``` python
|
|
1026
|
-
from cjm_transcript_source_select.components.source_browser import
|
|
1019
|
+
from cjm_transcript_source_select.components.source_browser import (
|
|
1020
|
+
SOURCE_BROWSER_COLUMNS,
|
|
1021
|
+
SB_SYSTEM_ID,
|
|
1022
|
+
SourceBrowserItem,
|
|
1023
|
+
build_source_items,
|
|
1024
|
+
is_source_item_skippable,
|
|
1025
|
+
create_source_cell_renderer,
|
|
1026
|
+
render_source_empty
|
|
1027
|
+
)
|
|
1027
1028
|
```
|
|
1028
1029
|
|
|
1029
1030
|
#### Functions
|
|
@@ -1037,65 +1038,139 @@ def _render_grouping_selector(
|
|
|
1037
1038
|
```
|
|
1038
1039
|
|
|
1039
1040
|
``` python
|
|
1040
|
-
def
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
is_first: bool = False, # Whether this is the first row (gets initial focus)
|
|
1047
|
-
row_index: int = 0, # Index among selectable rows (for keyboard focus sync)
|
|
1048
|
-
) -> Any: # Table row element
|
|
1049
|
-
"Render a single source row in the browser table."
|
|
1041
|
+
def build_source_items(
|
|
1042
|
+
transcriptions: List[Dict[str, Any]], # Available transcription records
|
|
1043
|
+
selected_sources: List[Dict[str, str]], # Currently selected sources
|
|
1044
|
+
grouping_mode: str = "media_path", # Grouping mode: "media_path" or "batch_id"
|
|
1045
|
+
) -> List[SourceBrowserItem]: # Flat list with interleaved headers and records
|
|
1046
|
+
"Build the items list for the source browser virtual collection."
|
|
1050
1047
|
```
|
|
1051
1048
|
|
|
1052
1049
|
``` python
|
|
1053
|
-
def
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
grouping_mode: str = "media_path", # Current grouping mode
|
|
1058
|
-
) -> Any: # Table row for group header
|
|
1059
|
-
"Render a group header row."
|
|
1050
|
+
def is_source_item_skippable(
|
|
1051
|
+
item: SourceBrowserItem, # Item to check
|
|
1052
|
+
) -> bool: # True if item is a group header (cursor should skip)
|
|
1053
|
+
"Predicate for virtual collection is_skippable parameter."
|
|
1060
1054
|
```
|
|
1061
1055
|
|
|
1062
1056
|
``` python
|
|
1063
|
-
def
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
select_all_url: str, # URL for selecting all in group
|
|
1067
|
-
) -> Any: #
|
|
1068
|
-
"Render
|
|
1057
|
+
def _render_header_cell(
|
|
1058
|
+
item: SourceBrowserItem, # Header item
|
|
1059
|
+
ctx: CellRenderContext, # Cell render context
|
|
1060
|
+
select_all_url: str = "", # URL for selecting all in group
|
|
1061
|
+
) -> Any: # Cell content for a group header row
|
|
1062
|
+
"Render cell content for a group header item."
|
|
1069
1063
|
```
|
|
1070
1064
|
|
|
1071
1065
|
``` python
|
|
1072
|
-
def
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
select_all_url: str, # URL for selecting all in a group
|
|
1079
|
-
grouping_mode: str = "media_path", # Grouping mode: "media_path" or "batch_id"
|
|
1080
|
-
oob: bool = False, # Whether to include hx-swap-oob for out-of-band swap
|
|
1081
|
-
) -> Any: # Source list container with table
|
|
1082
|
-
"Render the source list table with grouped rows."
|
|
1066
|
+
def _render_record_cell(
|
|
1067
|
+
item: SourceBrowserItem, # Record item
|
|
1068
|
+
ctx: CellRenderContext, # Cell render context
|
|
1069
|
+
toggle_url: str = "", # URL for toggling source selection
|
|
1070
|
+
) -> Any: # Cell content for a data record row
|
|
1071
|
+
"Render cell content for a data record item."
|
|
1083
1072
|
```
|
|
1084
1073
|
|
|
1085
1074
|
``` python
|
|
1086
|
-
def
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1075
|
+
def create_source_cell_renderer(
|
|
1076
|
+
toggle_url: str = "", # URL for toggling source selection
|
|
1077
|
+
select_all_url: str = "", # URL for selecting all in a group
|
|
1078
|
+
) -> Callable: # render_cell(item: SourceBrowserItem, ctx: CellRenderContext) -> Any
|
|
1079
|
+
"Create a render_cell callback for the source browser virtual collection."
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
``` python
|
|
1083
|
+
def render_source_empty() -> Any: # Empty state component
|
|
1084
|
+
"Render empty state when no transcription sources are available."
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
``` python
|
|
1088
|
+
def _render_source_browser_vc_content(
|
|
1089
|
+
sb_state: Any, # SourceBrowserRouterState from routes.source_browser
|
|
1090
|
+
) -> Any: # VC content wrapper (without search/grouping header)
|
|
1091
|
+
"Render the VC content portion of the source browser."
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
``` python
|
|
1095
|
+
def _render_source_browser_vc(
|
|
1096
|
+
sb_state: Any, # SourceBrowserRouterState from routes.source_browser
|
|
1097
|
+
filter_url: str = "", # URL for filtering sources
|
|
1095
1098
|
grouping_mode: str = "media_path", # Current grouping mode
|
|
1096
1099
|
grouping_change_url: str = "", # URL for changing grouping mode
|
|
1097
|
-
) -> Any: # Source browser component
|
|
1098
|
-
"Render the source browser panel
|
|
1100
|
+
) -> Any: # Source browser component with virtual collection
|
|
1101
|
+
"Render the full source browser panel (header + VC content)."
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
#### Classes
|
|
1105
|
+
|
|
1106
|
+
``` python
|
|
1107
|
+
@dataclass
|
|
1108
|
+
class SourceBrowserItem:
|
|
1109
|
+
"Item in the source browser virtual collection (header or record)."
|
|
1110
|
+
|
|
1111
|
+
item_type: str # "header" or "record"
|
|
1112
|
+
group_key: str = '' # Group key (media_path or batch_id value)
|
|
1113
|
+
group_display: str = '' # Formatted display text for group header
|
|
1114
|
+
group_count: int = 0 # Number of records in this group
|
|
1115
|
+
grouping_mode: str = '' # Grouping mode used ("media_path" or "batch_id")
|
|
1116
|
+
record: Optional[Dict[str, Any]] # Original transcription record dict
|
|
1117
|
+
is_selected: bool = False # Whether currently in queue
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
#### Variables
|
|
1121
|
+
|
|
1122
|
+
``` python
|
|
1123
|
+
SOURCE_BROWSER_COLUMNS
|
|
1124
|
+
_SB_CONTENT_ID = 'sb-content'
|
|
1125
|
+
_SB_VC_WRAPPER_ID = 'sb-vc-wrapper'
|
|
1126
|
+
SB_SYSTEM_ID = 'sb-collection'
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
### source_browser (`source_browser.ipynb`)
|
|
1130
|
+
|
|
1131
|
+
> Source browser virtual collection router for Phase 1 selection
|
|
1132
|
+
|
|
1133
|
+
#### Import
|
|
1134
|
+
|
|
1135
|
+
``` python
|
|
1136
|
+
from cjm_transcript_source_select.routes.source_browser import (
|
|
1137
|
+
SourceBrowserRouterState,
|
|
1138
|
+
init_source_browser_router
|
|
1139
|
+
)
|
|
1140
|
+
```
|
|
1141
|
+
|
|
1142
|
+
#### Functions
|
|
1143
|
+
|
|
1144
|
+
``` python
|
|
1145
|
+
def init_source_browser_router(
|
|
1146
|
+
source_service: SourceService, # Source service for querying transcriptions
|
|
1147
|
+
urls: SelectionUrls, # URL bundle (toggle, select_all, filter, grouping_change)
|
|
1148
|
+
prefix: str = "/browser", # Route prefix for VC routes
|
|
1149
|
+
) -> SourceBrowserRouterState: # Router state with all VC objects and helpers
|
|
1150
|
+
"Initialize the source browser virtual collection router."
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
#### Classes
|
|
1154
|
+
|
|
1155
|
+
``` python
|
|
1156
|
+
@dataclass
|
|
1157
|
+
class SourceBrowserRouterState:
|
|
1158
|
+
"Return value from init_source_browser_router."
|
|
1159
|
+
|
|
1160
|
+
router: APIRouter # VC routes (nav, focus, activate, sort, viewport)
|
|
1161
|
+
urls: VirtualCollectionUrls # VC URL bundle
|
|
1162
|
+
ids: VirtualCollectionHtmlIds # VC HTML IDs
|
|
1163
|
+
btn_ids: VirtualCollectionButtonIds # VC keyboard button IDs
|
|
1164
|
+
config: VirtualCollectionConfig # VC config
|
|
1165
|
+
state: VirtualCollectionState # VC state (mutable)
|
|
1166
|
+
items: List[SourceBrowserItem] # Shared items list (mutable)
|
|
1167
|
+
render_cell: Callable # Cell render callback
|
|
1168
|
+
rebuild_and_render: Callable # (transcriptions, selected_sources, grouping_mode, content_only) -> Div
|
|
1169
|
+
rebuild_items: Callable # (transcriptions, selected_sources, grouping_mode) -> None
|
|
1170
|
+
sync_items_selection: Callable # (selected_sources) -> None
|
|
1171
|
+
get_visible_checkbox_oobs: Callable # () -> tuple of OOB elements
|
|
1172
|
+
get_checkbox_oob_for: Callable # (record_id, provider_id) -> OOB element or None
|
|
1173
|
+
get_vc_row_id_for: Callable # (record_id, provider_id) -> str or None
|
|
1099
1174
|
```
|
|
1100
1175
|
|
|
1101
1176
|
### source_utils (`source_utils.ipynb`)
|
|
@@ -1252,13 +1327,13 @@ def validate_browse_path(
|
|
|
1252
1327
|
from cjm_transcript_source_select.components.step_renderer import (
|
|
1253
1328
|
SD_FOCUSED_RECORD_ID_INPUT,
|
|
1254
1329
|
SD_FOCUSED_PROVIDER_ID_INPUT,
|
|
1255
|
-
SD_TOGGLE_BTN,
|
|
1256
1330
|
SD_REMOVE_BTN,
|
|
1257
1331
|
SD_REORDER_UP_BTN,
|
|
1258
1332
|
SD_REORDER_DOWN_BTN,
|
|
1259
1333
|
SD_TAB_PREV_BTN,
|
|
1260
1334
|
SD_TAB_NEXT_BTN,
|
|
1261
1335
|
SD_PREVIEW_BTN,
|
|
1336
|
+
FB_SYSTEM_ID,
|
|
1262
1337
|
render_selection_step
|
|
1263
1338
|
)
|
|
1264
1339
|
```
|
|
@@ -1266,8 +1341,8 @@ from cjm_transcript_source_select.components.step_renderer import (
|
|
|
1266
1341
|
#### Functions
|
|
1267
1342
|
|
|
1268
1343
|
``` python
|
|
1269
|
-
def
|
|
1270
|
-
"Create the keyboard
|
|
1344
|
+
def _create_parent_keyboard_manager() -> ZoneManager: # Parent keyboard manager for hierarchy
|
|
1345
|
+
"Create the parent keyboard manager for the selection step."
|
|
1271
1346
|
```
|
|
1272
1347
|
|
|
1273
1348
|
``` python
|
|
@@ -1313,19 +1388,10 @@ def _render_source_tabs(
|
|
|
1313
1388
|
```
|
|
1314
1389
|
|
|
1315
1390
|
``` python
|
|
1316
|
-
def
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
"Get or create the local files provider for step renderer."
|
|
1321
|
-
```
|
|
1322
|
-
|
|
1323
|
-
``` python
|
|
1324
|
-
def _get_step_renderer_config():
|
|
1325
|
-
"""Get or create the local files config for step renderer."""
|
|
1326
|
-
global _step_renderer_config
|
|
1327
|
-
if _step_renderer_config is None
|
|
1328
|
-
"Get or create the local files config for step renderer."
|
|
1391
|
+
def _generate_hierarchy_js(
|
|
1392
|
+
active_tab: str, # Active tab: "db" or "files"
|
|
1393
|
+
) -> Script: # Script element with hierarchy wiring and activation logic
|
|
1394
|
+
"Generate JavaScript for keyboard system hierarchy and child activation."
|
|
1329
1395
|
```
|
|
1330
1396
|
|
|
1331
1397
|
``` python
|
|
@@ -1334,10 +1400,10 @@ def render_selection_step(
|
|
|
1334
1400
|
transcriptions: List[Dict[str, Any]], # Available transcription records
|
|
1335
1401
|
selected_sources: List[Dict[str, str]], # Ordered selection
|
|
1336
1402
|
grouping_mode: str, # Grouping mode: "media_path" or "batch_id"
|
|
1337
|
-
external_db_paths: List[str], # External database paths
|
|
1338
|
-
file_browser_state: Dict[str, Any], # Serialized BrowserState from file-browser library
|
|
1339
1403
|
active_tab: str, # Active tab: "db" or "files"
|
|
1340
1404
|
urls: SelectionUrls, # URL bundle for selection routes
|
|
1405
|
+
render_local_files_panel: Optional[Callable] = None, # Render fn for Files tab content
|
|
1406
|
+
sb_state: Any = None, # SourceBrowserRouterState for DB tab VC rendering
|
|
1341
1407
|
) -> Any: # FastHTML component
|
|
1342
1408
|
"Render Phase 1: Source Selection & Ordering step with two-column layout."
|
|
1343
1409
|
```
|
|
@@ -1347,14 +1413,13 @@ def render_selection_step(
|
|
|
1347
1413
|
``` python
|
|
1348
1414
|
SD_FOCUSED_RECORD_ID_INPUT = 'sd-focused-record-id'
|
|
1349
1415
|
SD_FOCUSED_PROVIDER_ID_INPUT = 'sd-focused-provider-id'
|
|
1350
|
-
SD_TOGGLE_BTN = 'sd-toggle-btn'
|
|
1351
1416
|
SD_REMOVE_BTN = 'sd-remove-btn'
|
|
1352
1417
|
SD_REORDER_UP_BTN = 'sd-reorder-up-btn'
|
|
1353
1418
|
SD_REORDER_DOWN_BTN = 'sd-reorder-down-btn'
|
|
1354
1419
|
SD_TAB_PREV_BTN = 'sd-tab-prev-btn'
|
|
1355
1420
|
SD_TAB_NEXT_BTN = 'sd-tab-next-btn'
|
|
1356
1421
|
SD_PREVIEW_BTN = 'sd-preview-btn'
|
|
1357
|
-
|
|
1422
|
+
FB_SYSTEM_ID = 'lfb-collection'
|
|
1358
1423
|
_VIEWPORT_FIT_CONFIG
|
|
1359
1424
|
```
|
|
1360
1425
|
|
|
@@ -1381,7 +1446,9 @@ def _handle_tab_switch(
|
|
|
1381
1446
|
sess, # FastHTML session object
|
|
1382
1447
|
direction: str, # Direction: "prev", "next", "db", or "files"
|
|
1383
1448
|
urls: SelectionUrls, # URL bundle for rendering
|
|
1384
|
-
|
|
1449
|
+
render_local_files_panel: Optional[Callable] = None, # Render fn for Files tab
|
|
1450
|
+
sb_state: Any = None, # SourceBrowserRouterState for DB tab VC rendering
|
|
1451
|
+
): # Tuple of inner content, OOB tab headers, and tab switch script
|
|
1385
1452
|
"Switch between Plugin DB and Local Files tabs."
|
|
1386
1453
|
```
|
|
1387
1454
|
|
|
@@ -1392,6 +1459,8 @@ def init_tabs_router(
|
|
|
1392
1459
|
source_service: SourceService, # The source service for queries
|
|
1393
1460
|
prefix: str, # Route prefix (e.g., "/workflow/selection/tabs")
|
|
1394
1461
|
urls: SelectionUrls, # URL bundle for rendering
|
|
1462
|
+
render_local_files_panel: Optional[Callable] = None, # Render fn for Files tab content
|
|
1463
|
+
sb_state: Any = None, # SourceBrowserRouterState for DB tab VC rendering
|
|
1395
1464
|
) -> Tuple[APIRouter, Dict[str, Callable]]: # (router, route_dict)
|
|
1396
1465
|
"Initialize tab switching routes."
|
|
1397
1466
|
```
|