cjm-transcript-source-select 0.0.14__tar.gz → 0.0.15__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.14/cjm_transcript_source_select.egg-info → cjm_transcript_source_select-0.0.15}/PKG-INFO +65 -26
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/README.md +64 -25
- cjm_transcript_source_select-0.0.15/cjm_transcript_source_select/__init__.py +1 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/_modidx.py +8 -2
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/models.py +28 -3
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/init.py +15 -8
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/local_files.py +73 -7
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/tabs.py +16 -13
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15/cjm_transcript_source_select.egg-info}/PKG-INFO +65 -26
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/settings.ini +1 -1
- cjm_transcript_source_select-0.0.14/cjm_transcript_source_select/__init__.py +0 -1
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/LICENSE +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/MANIFEST.in +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/components/__init__.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/components/helpers.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/components/local_files.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/components/preview_panel.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/components/selection_queue.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/components/source_browser.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/components/step_renderer.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/html_ids.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/__init__.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/core.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/filtering.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/queue.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/routes/source_browser.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/services/__init__.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/services/source.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/services/source_utils.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select/utils.py +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select.egg-info/SOURCES.txt +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select.egg-info/dependency_links.txt +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select.egg-info/entry_points.txt +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select.egg-info/not-zip-safe +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select.egg-info/requires.txt +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/cjm_transcript_source_select.egg-info/top_level.txt +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/pyproject.toml +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/setup.cfg +0 -0
- {cjm_transcript_source_select-0.0.14 → cjm_transcript_source_select-0.0.15}/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.15
|
|
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
|
|
@@ -106,57 +106,57 @@ graph LR
|
|
|
106
106
|
utils[utils<br/>utils]
|
|
107
107
|
|
|
108
108
|
components_helpers --> models
|
|
109
|
-
components_local_files --> components_helpers
|
|
110
109
|
components_local_files --> html_ids
|
|
110
|
+
components_local_files --> components_helpers
|
|
111
111
|
components_preview_panel --> html_ids
|
|
112
112
|
components_source_browser --> services_source_utils
|
|
113
113
|
components_source_browser --> utils
|
|
114
114
|
components_source_browser --> html_ids
|
|
115
115
|
components_step_renderer --> components_preview_panel
|
|
116
|
-
components_step_renderer --> models
|
|
117
|
-
components_step_renderer --> utils
|
|
118
|
-
components_step_renderer --> components_source_browser
|
|
119
116
|
components_step_renderer --> components_selection_queue
|
|
117
|
+
components_step_renderer --> utils
|
|
120
118
|
components_step_renderer --> components_local_files
|
|
121
119
|
components_step_renderer --> html_ids
|
|
120
|
+
components_step_renderer --> models
|
|
121
|
+
components_step_renderer --> components_source_browser
|
|
122
122
|
routes_core --> models
|
|
123
|
+
routes_core --> services_source
|
|
124
|
+
routes_core --> components_selection_queue
|
|
123
125
|
routes_core --> components_step_renderer
|
|
124
126
|
routes_core --> html_ids
|
|
125
|
-
routes_core --> components_selection_queue
|
|
126
|
-
routes_core --> services_source
|
|
127
|
-
routes_filtering --> models
|
|
128
127
|
routes_filtering --> routes_core
|
|
129
128
|
routes_filtering --> services_source_utils
|
|
130
129
|
routes_filtering --> services_source
|
|
130
|
+
routes_filtering --> models
|
|
131
131
|
routes_init --> routes_core
|
|
132
132
|
routes_init --> routes_queue
|
|
133
|
-
routes_init --> models
|
|
134
|
-
routes_init --> routes_local_files
|
|
135
|
-
routes_init --> routes_source_browser
|
|
136
|
-
routes_init --> routes_filtering
|
|
137
133
|
routes_init --> routes_tabs
|
|
134
|
+
routes_init --> routes_filtering
|
|
138
135
|
routes_init --> services_source
|
|
139
|
-
|
|
136
|
+
routes_init --> routes_source_browser
|
|
137
|
+
routes_init --> routes_local_files
|
|
138
|
+
routes_init --> models
|
|
140
139
|
routes_local_files --> models
|
|
141
|
-
routes_local_files --> services_source
|
|
142
140
|
routes_local_files --> routes_core
|
|
143
|
-
|
|
141
|
+
routes_local_files --> components_local_files
|
|
142
|
+
routes_local_files --> services_source
|
|
144
143
|
routes_queue --> routes_core
|
|
144
|
+
routes_queue --> services_source_utils
|
|
145
145
|
routes_queue --> components_preview_panel
|
|
146
|
-
routes_queue --> models
|
|
147
146
|
routes_queue --> services_source
|
|
148
|
-
|
|
149
|
-
routes_source_browser --> components_preview_panel
|
|
150
|
-
routes_source_browser --> models
|
|
147
|
+
routes_queue --> models
|
|
151
148
|
routes_source_browser --> components_source_browser
|
|
149
|
+
routes_source_browser --> components_preview_panel
|
|
152
150
|
routes_source_browser --> services_source_utils
|
|
153
151
|
routes_source_browser --> services_source
|
|
152
|
+
routes_source_browser --> routes_core
|
|
154
153
|
routes_source_browser --> html_ids
|
|
155
|
-
|
|
156
|
-
routes_tabs --> services_source_utils
|
|
154
|
+
routes_source_browser --> models
|
|
157
155
|
routes_tabs --> models
|
|
158
156
|
routes_tabs --> components_step_renderer
|
|
159
157
|
routes_tabs --> services_source
|
|
158
|
+
routes_tabs --> routes_core
|
|
159
|
+
routes_tabs --> services_source_utils
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
*52 cross-module dependencies detected*
|
|
@@ -426,7 +426,7 @@ def init_selection_routers(
|
|
|
426
426
|
source_service: SourceService, # The source service for queries
|
|
427
427
|
workflow_id: str, # The workflow identifier
|
|
428
428
|
prefix: str, # Base prefix for selection routes (e.g., "/workflow/selection")
|
|
429
|
-
) ->
|
|
429
|
+
) -> SelectionResult: # Selection router result with routers, urls, routes, and restore
|
|
430
430
|
"Initialize and return all selection routers with URL bundle."
|
|
431
431
|
```
|
|
432
432
|
|
|
@@ -539,7 +539,7 @@ def init_local_files_router(
|
|
|
539
539
|
source_service: SourceService, # The source service for external db ops
|
|
540
540
|
prefix: str, # Route prefix (e.g., "/workflow/selection/local_files")
|
|
541
541
|
urls: SelectionUrls, # URL bundle for rendering
|
|
542
|
-
) ->
|
|
542
|
+
) -> LocalFilesResult: # Router result with routers, routes, render, and restore
|
|
543
543
|
"Initialize local files browser routes with new file browser API."
|
|
544
544
|
```
|
|
545
545
|
|
|
@@ -558,10 +558,24 @@ _local_files_provider: Optional[LocalFileSystemProvider] = None
|
|
|
558
558
|
``` python
|
|
559
559
|
from cjm_transcript_source_select.models import (
|
|
560
560
|
SelectionStepState,
|
|
561
|
-
SelectionUrls
|
|
561
|
+
SelectionUrls,
|
|
562
|
+
LocalFilesResult,
|
|
563
|
+
SelectionResult
|
|
562
564
|
)
|
|
563
565
|
```
|
|
564
566
|
|
|
567
|
+
#### Functions
|
|
568
|
+
|
|
569
|
+
``` python
|
|
570
|
+
def _no_op_restore(session_id: str) -> None:
|
|
571
|
+
"""Default no-op for restore_state."""
|
|
572
|
+
pass
|
|
573
|
+
|
|
574
|
+
@dataclass
|
|
575
|
+
class LocalFilesResult
|
|
576
|
+
"Default no-op for restore_state."
|
|
577
|
+
```
|
|
578
|
+
|
|
565
579
|
#### Classes
|
|
566
580
|
|
|
567
581
|
``` python
|
|
@@ -591,6 +605,30 @@ class SelectionUrls:
|
|
|
591
605
|
tab_switch: str = '' # Switch source tabs
|
|
592
606
|
```
|
|
593
607
|
|
|
608
|
+
``` python
|
|
609
|
+
@dataclass
|
|
610
|
+
class LocalFilesResult:
|
|
611
|
+
"Return type from init_local_files_router."
|
|
612
|
+
|
|
613
|
+
routers: List[APIRouter] # Routers to register (custom + file browser + VC)
|
|
614
|
+
routes: Dict[str, Callable] # Named route handlers
|
|
615
|
+
render_panel: Callable # (error_message?, session_id?) -> rendered panel
|
|
616
|
+
restore_state: Callable = field(...) # (session_id) -> None, restore persisted state
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
``` python
|
|
620
|
+
@dataclass
|
|
621
|
+
class SelectionResult:
|
|
622
|
+
"Return type from init_selection_routers."
|
|
623
|
+
|
|
624
|
+
routers: List[APIRouter] # All selection routers to register
|
|
625
|
+
urls: 'SelectionUrls' = field(...) # URL bundle
|
|
626
|
+
routes: Dict[str, Callable] = field(...) # All named route handlers
|
|
627
|
+
render_local_files_panel: Optional[Callable] # Render fn for local files tab
|
|
628
|
+
sb_state: Any # SourceBrowserRouterState
|
|
629
|
+
restore_state: Callable = field(...) # (session_id) -> None, restore persisted state
|
|
630
|
+
```
|
|
631
|
+
|
|
594
632
|
### preview_panel (`preview_panel.ipynb`)
|
|
595
633
|
|
|
596
634
|
> Collapsible preview panel for displaying selected content
|
|
@@ -1434,15 +1472,16 @@ from cjm_transcript_source_select.routes.tabs import (
|
|
|
1434
1472
|
|
|
1435
1473
|
``` python
|
|
1436
1474
|
def _handle_tab_switch(
|
|
1437
|
-
state_store: WorkflowStateStore, # The workflow state store
|
|
1438
|
-
workflow_id: str, # The workflow identifier
|
|
1439
1475
|
source_service: SourceService, # The source service for queries
|
|
1440
1476
|
request, # FastHTML request object
|
|
1441
1477
|
sess, # FastHTML session object
|
|
1442
1478
|
direction: str, # Direction: "prev", "next", "db", or "files"
|
|
1443
1479
|
urls: SelectionUrls, # URL bundle for rendering
|
|
1480
|
+
current_tab_ref: List[str], # Mutable ref [current_tab] for closure-based tracking
|
|
1444
1481
|
render_local_files_panel: Optional[Callable] = None, # Render fn for Files tab
|
|
1445
1482
|
sb_state: Any = None, # SourceBrowserRouterState for DB tab VC rendering
|
|
1483
|
+
state_store: WorkflowStateStore = None, # State store (for reading step state)
|
|
1484
|
+
workflow_id: str = "", # Workflow ID (for reading step state)
|
|
1446
1485
|
): # Tuple of inner content, OOB tab headers, and tab switch script
|
|
1447
1486
|
"Switch between Plugin DB and Local Files tabs."
|
|
1448
1487
|
```
|
|
@@ -60,57 +60,57 @@ graph LR
|
|
|
60
60
|
utils[utils<br/>utils]
|
|
61
61
|
|
|
62
62
|
components_helpers --> models
|
|
63
|
-
components_local_files --> components_helpers
|
|
64
63
|
components_local_files --> html_ids
|
|
64
|
+
components_local_files --> components_helpers
|
|
65
65
|
components_preview_panel --> html_ids
|
|
66
66
|
components_source_browser --> services_source_utils
|
|
67
67
|
components_source_browser --> utils
|
|
68
68
|
components_source_browser --> html_ids
|
|
69
69
|
components_step_renderer --> components_preview_panel
|
|
70
|
-
components_step_renderer --> models
|
|
71
|
-
components_step_renderer --> utils
|
|
72
|
-
components_step_renderer --> components_source_browser
|
|
73
70
|
components_step_renderer --> components_selection_queue
|
|
71
|
+
components_step_renderer --> utils
|
|
74
72
|
components_step_renderer --> components_local_files
|
|
75
73
|
components_step_renderer --> html_ids
|
|
74
|
+
components_step_renderer --> models
|
|
75
|
+
components_step_renderer --> components_source_browser
|
|
76
76
|
routes_core --> models
|
|
77
|
+
routes_core --> services_source
|
|
78
|
+
routes_core --> components_selection_queue
|
|
77
79
|
routes_core --> components_step_renderer
|
|
78
80
|
routes_core --> html_ids
|
|
79
|
-
routes_core --> components_selection_queue
|
|
80
|
-
routes_core --> services_source
|
|
81
|
-
routes_filtering --> models
|
|
82
81
|
routes_filtering --> routes_core
|
|
83
82
|
routes_filtering --> services_source_utils
|
|
84
83
|
routes_filtering --> services_source
|
|
84
|
+
routes_filtering --> models
|
|
85
85
|
routes_init --> routes_core
|
|
86
86
|
routes_init --> routes_queue
|
|
87
|
-
routes_init --> models
|
|
88
|
-
routes_init --> routes_local_files
|
|
89
|
-
routes_init --> routes_source_browser
|
|
90
|
-
routes_init --> routes_filtering
|
|
91
87
|
routes_init --> routes_tabs
|
|
88
|
+
routes_init --> routes_filtering
|
|
92
89
|
routes_init --> services_source
|
|
93
|
-
|
|
90
|
+
routes_init --> routes_source_browser
|
|
91
|
+
routes_init --> routes_local_files
|
|
92
|
+
routes_init --> models
|
|
94
93
|
routes_local_files --> models
|
|
95
|
-
routes_local_files --> services_source
|
|
96
94
|
routes_local_files --> routes_core
|
|
97
|
-
|
|
95
|
+
routes_local_files --> components_local_files
|
|
96
|
+
routes_local_files --> services_source
|
|
98
97
|
routes_queue --> routes_core
|
|
98
|
+
routes_queue --> services_source_utils
|
|
99
99
|
routes_queue --> components_preview_panel
|
|
100
|
-
routes_queue --> models
|
|
101
100
|
routes_queue --> services_source
|
|
102
|
-
|
|
103
|
-
routes_source_browser --> components_preview_panel
|
|
104
|
-
routes_source_browser --> models
|
|
101
|
+
routes_queue --> models
|
|
105
102
|
routes_source_browser --> components_source_browser
|
|
103
|
+
routes_source_browser --> components_preview_panel
|
|
106
104
|
routes_source_browser --> services_source_utils
|
|
107
105
|
routes_source_browser --> services_source
|
|
106
|
+
routes_source_browser --> routes_core
|
|
108
107
|
routes_source_browser --> html_ids
|
|
109
|
-
|
|
110
|
-
routes_tabs --> services_source_utils
|
|
108
|
+
routes_source_browser --> models
|
|
111
109
|
routes_tabs --> models
|
|
112
110
|
routes_tabs --> components_step_renderer
|
|
113
111
|
routes_tabs --> services_source
|
|
112
|
+
routes_tabs --> routes_core
|
|
113
|
+
routes_tabs --> services_source_utils
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
*52 cross-module dependencies detected*
|
|
@@ -380,7 +380,7 @@ def init_selection_routers(
|
|
|
380
380
|
source_service: SourceService, # The source service for queries
|
|
381
381
|
workflow_id: str, # The workflow identifier
|
|
382
382
|
prefix: str, # Base prefix for selection routes (e.g., "/workflow/selection")
|
|
383
|
-
) ->
|
|
383
|
+
) -> SelectionResult: # Selection router result with routers, urls, routes, and restore
|
|
384
384
|
"Initialize and return all selection routers with URL bundle."
|
|
385
385
|
```
|
|
386
386
|
|
|
@@ -493,7 +493,7 @@ def init_local_files_router(
|
|
|
493
493
|
source_service: SourceService, # The source service for external db ops
|
|
494
494
|
prefix: str, # Route prefix (e.g., "/workflow/selection/local_files")
|
|
495
495
|
urls: SelectionUrls, # URL bundle for rendering
|
|
496
|
-
) ->
|
|
496
|
+
) -> LocalFilesResult: # Router result with routers, routes, render, and restore
|
|
497
497
|
"Initialize local files browser routes with new file browser API."
|
|
498
498
|
```
|
|
499
499
|
|
|
@@ -512,10 +512,24 @@ _local_files_provider: Optional[LocalFileSystemProvider] = None
|
|
|
512
512
|
``` python
|
|
513
513
|
from cjm_transcript_source_select.models import (
|
|
514
514
|
SelectionStepState,
|
|
515
|
-
SelectionUrls
|
|
515
|
+
SelectionUrls,
|
|
516
|
+
LocalFilesResult,
|
|
517
|
+
SelectionResult
|
|
516
518
|
)
|
|
517
519
|
```
|
|
518
520
|
|
|
521
|
+
#### Functions
|
|
522
|
+
|
|
523
|
+
``` python
|
|
524
|
+
def _no_op_restore(session_id: str) -> None:
|
|
525
|
+
"""Default no-op for restore_state."""
|
|
526
|
+
pass
|
|
527
|
+
|
|
528
|
+
@dataclass
|
|
529
|
+
class LocalFilesResult
|
|
530
|
+
"Default no-op for restore_state."
|
|
531
|
+
```
|
|
532
|
+
|
|
519
533
|
#### Classes
|
|
520
534
|
|
|
521
535
|
``` python
|
|
@@ -545,6 +559,30 @@ class SelectionUrls:
|
|
|
545
559
|
tab_switch: str = '' # Switch source tabs
|
|
546
560
|
```
|
|
547
561
|
|
|
562
|
+
``` python
|
|
563
|
+
@dataclass
|
|
564
|
+
class LocalFilesResult:
|
|
565
|
+
"Return type from init_local_files_router."
|
|
566
|
+
|
|
567
|
+
routers: List[APIRouter] # Routers to register (custom + file browser + VC)
|
|
568
|
+
routes: Dict[str, Callable] # Named route handlers
|
|
569
|
+
render_panel: Callable # (error_message?, session_id?) -> rendered panel
|
|
570
|
+
restore_state: Callable = field(...) # (session_id) -> None, restore persisted state
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
``` python
|
|
574
|
+
@dataclass
|
|
575
|
+
class SelectionResult:
|
|
576
|
+
"Return type from init_selection_routers."
|
|
577
|
+
|
|
578
|
+
routers: List[APIRouter] # All selection routers to register
|
|
579
|
+
urls: 'SelectionUrls' = field(...) # URL bundle
|
|
580
|
+
routes: Dict[str, Callable] = field(...) # All named route handlers
|
|
581
|
+
render_local_files_panel: Optional[Callable] # Render fn for local files tab
|
|
582
|
+
sb_state: Any # SourceBrowserRouterState
|
|
583
|
+
restore_state: Callable = field(...) # (session_id) -> None, restore persisted state
|
|
584
|
+
```
|
|
585
|
+
|
|
548
586
|
### preview_panel (`preview_panel.ipynb`)
|
|
549
587
|
|
|
550
588
|
> Collapsible preview panel for displaying selected content
|
|
@@ -1388,15 +1426,16 @@ from cjm_transcript_source_select.routes.tabs import (
|
|
|
1388
1426
|
|
|
1389
1427
|
``` python
|
|
1390
1428
|
def _handle_tab_switch(
|
|
1391
|
-
state_store: WorkflowStateStore, # The workflow state store
|
|
1392
|
-
workflow_id: str, # The workflow identifier
|
|
1393
1429
|
source_service: SourceService, # The source service for queries
|
|
1394
1430
|
request, # FastHTML request object
|
|
1395
1431
|
sess, # FastHTML session object
|
|
1396
1432
|
direction: str, # Direction: "prev", "next", "db", or "files"
|
|
1397
1433
|
urls: SelectionUrls, # URL bundle for rendering
|
|
1434
|
+
current_tab_ref: List[str], # Mutable ref [current_tab] for closure-based tracking
|
|
1398
1435
|
render_local_files_panel: Optional[Callable] = None, # Render fn for Files tab
|
|
1399
1436
|
sb_state: Any = None, # SourceBrowserRouterState for DB tab VC rendering
|
|
1437
|
+
state_store: WorkflowStateStore = None, # State store (for reading step state)
|
|
1438
|
+
workflow_id: str = "", # Workflow ID (for reading step state)
|
|
1400
1439
|
): # Tuple of inner content, OOB tab headers, and tab switch script
|
|
1401
1440
|
"Switch between Plugin DB and Local Files tabs."
|
|
1402
1441
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.15"
|
|
@@ -81,10 +81,16 @@ d = { 'settings': { 'branch': 'main',
|
|
|
81
81
|
'cjm_transcript_source_select/html_ids.py'),
|
|
82
82
|
'cjm_transcript_source_select.html_ids.SelectionHtmlIds.source_row': ( 'html_ids.html#selectionhtmlids.source_row',
|
|
83
83
|
'cjm_transcript_source_select/html_ids.py')},
|
|
84
|
-
'cjm_transcript_source_select.models': { 'cjm_transcript_source_select.models.
|
|
84
|
+
'cjm_transcript_source_select.models': { 'cjm_transcript_source_select.models.LocalFilesResult': ( 'models.html#localfilesresult',
|
|
85
|
+
'cjm_transcript_source_select/models.py'),
|
|
86
|
+
'cjm_transcript_source_select.models.SelectionResult': ( 'models.html#selectionresult',
|
|
87
|
+
'cjm_transcript_source_select/models.py'),
|
|
88
|
+
'cjm_transcript_source_select.models.SelectionStepState': ( 'models.html#selectionstepstate',
|
|
85
89
|
'cjm_transcript_source_select/models.py'),
|
|
86
90
|
'cjm_transcript_source_select.models.SelectionUrls': ( 'models.html#selectionurls',
|
|
87
|
-
'cjm_transcript_source_select/models.py')
|
|
91
|
+
'cjm_transcript_source_select/models.py'),
|
|
92
|
+
'cjm_transcript_source_select.models._no_op_restore': ( 'models.html#_no_op_restore',
|
|
93
|
+
'cjm_transcript_source_select/models.py')},
|
|
88
94
|
'cjm_transcript_source_select.routes.core': { 'cjm_transcript_source_select.routes.core._build_queue_response': ( 'routes/core.html#_build_queue_response',
|
|
89
95
|
'cjm_transcript_source_select/routes/core.py'),
|
|
90
96
|
'cjm_transcript_source_select.routes.core._find_duplicate_media_source': ( 'routes/core.html#_find_duplicate_media_source',
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/models.ipynb.
|
|
4
4
|
|
|
5
5
|
# %% auto #0
|
|
6
|
-
__all__ = ['SelectionStepState', 'SelectionUrls']
|
|
6
|
+
__all__ = ['SelectionStepState', 'SelectionUrls', 'LocalFilesResult', 'SelectionResult']
|
|
7
7
|
|
|
8
8
|
# %% ../nbs/models.ipynb #selection-models-imports
|
|
9
|
-
from typing import List, Dict, Any
|
|
9
|
+
from typing import List, Dict, Any, Callable, Optional
|
|
10
10
|
from typing_extensions import TypedDict
|
|
11
|
-
from dataclasses import dataclass
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
|
|
13
|
+
from fasthtml.common import APIRouter
|
|
12
14
|
|
|
13
15
|
from cjm_source_provider.models import SelectedSource
|
|
14
16
|
|
|
@@ -51,3 +53,26 @@ class SelectionUrls:
|
|
|
51
53
|
|
|
52
54
|
# Tab switching
|
|
53
55
|
tab_switch: str = "" # Switch source tabs
|
|
56
|
+
|
|
57
|
+
# %% ../nbs/models.ipynb #gxc6wl5o4mn
|
|
58
|
+
def _no_op_restore(session_id: str) -> None:
|
|
59
|
+
"""Default no-op for restore_state."""
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class LocalFilesResult:
|
|
64
|
+
"""Return type from init_local_files_router."""
|
|
65
|
+
routers: List[APIRouter] # Routers to register (custom + file browser + VC)
|
|
66
|
+
routes: Dict[str, Callable] # Named route handlers
|
|
67
|
+
render_panel: Callable # (error_message?, session_id?) -> rendered panel
|
|
68
|
+
restore_state: Callable = field(default=_no_op_restore) # (session_id) -> None, restore persisted state
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class SelectionResult:
|
|
72
|
+
"""Return type from init_selection_routers."""
|
|
73
|
+
routers: List[APIRouter] # All selection routers to register
|
|
74
|
+
urls: "SelectionUrls" = field(default_factory=lambda: SelectionUrls()) # URL bundle
|
|
75
|
+
routes: Dict[str, Callable] = field(default_factory=dict) # All named route handlers
|
|
76
|
+
render_local_files_panel: Optional[Callable] = None # Render fn for local files tab
|
|
77
|
+
sb_state: Any = None # SourceBrowserRouterState
|
|
78
|
+
restore_state: Callable = field(default=_no_op_restore) # (session_id) -> None, restore persisted state
|
|
@@ -12,7 +12,7 @@ from fasthtml.common import APIRouter
|
|
|
12
12
|
|
|
13
13
|
from cjm_fasthtml_interactions.core.state_store import get_session_id
|
|
14
14
|
|
|
15
|
-
from ..models import SelectionUrls
|
|
15
|
+
from ..models import SelectionUrls, SelectionResult
|
|
16
16
|
from cjm_transcript_source_select.routes.core import (
|
|
17
17
|
WorkflowStateStore,
|
|
18
18
|
_rebuild_and_render_ref, _sync_items_ref,
|
|
@@ -32,7 +32,7 @@ def init_selection_routers(
|
|
|
32
32
|
source_service: SourceService, # The source service for queries
|
|
33
33
|
workflow_id: str, # The workflow identifier
|
|
34
34
|
prefix: str, # Base prefix for selection routes (e.g., "/workflow/selection")
|
|
35
|
-
) ->
|
|
35
|
+
) -> SelectionResult: # Selection router result with routers, urls, routes, and restore
|
|
36
36
|
"""Initialize and return all selection routers with URL bundle."""
|
|
37
37
|
urls = SelectionUrls()
|
|
38
38
|
|
|
@@ -42,7 +42,7 @@ def init_selection_routers(
|
|
|
42
42
|
filtering_router, filtering_routes = init_filtering_router(
|
|
43
43
|
state_store, workflow_id, source_service, f"{prefix}/filtering", urls
|
|
44
44
|
)
|
|
45
|
-
|
|
45
|
+
local_files = init_local_files_router(
|
|
46
46
|
state_store, workflow_id, source_service, f"{prefix}/local_files", urls
|
|
47
47
|
)
|
|
48
48
|
sb_state = init_source_browser_router(
|
|
@@ -92,7 +92,7 @@ def init_selection_routers(
|
|
|
92
92
|
|
|
93
93
|
tabs_router, tabs_routes = init_tabs_router(
|
|
94
94
|
state_store, workflow_id, source_service, f"{prefix}/tabs", urls,
|
|
95
|
-
render_local_files_panel=
|
|
95
|
+
render_local_files_panel=local_files.render_panel,
|
|
96
96
|
sb_state=sb_state,
|
|
97
97
|
)
|
|
98
98
|
|
|
@@ -108,16 +108,23 @@ def init_selection_routers(
|
|
|
108
108
|
urls.keyboard_reorder = filtering_routes["keyboard_reorder"].to()
|
|
109
109
|
urls.filter = filtering_routes["filter"].to()
|
|
110
110
|
urls.grouping_change = filtering_routes["grouping_change"].to()
|
|
111
|
-
urls.remove_external =
|
|
111
|
+
urls.remove_external = local_files.routes["remove_external"].to()
|
|
112
112
|
urls.tab_switch = tabs_routes["tab_switch"].to()
|
|
113
113
|
|
|
114
114
|
merged_routes = {
|
|
115
115
|
**queue_routes,
|
|
116
116
|
**filtering_routes,
|
|
117
|
-
**
|
|
117
|
+
**local_files.routes,
|
|
118
118
|
**tabs_routes,
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
routers = [queue_router, filtering_router, *
|
|
121
|
+
routers = [queue_router, filtering_router, *local_files.routers, tabs_router, sb_state.router]
|
|
122
122
|
|
|
123
|
-
return
|
|
123
|
+
return SelectionResult(
|
|
124
|
+
routers=routers,
|
|
125
|
+
urls=urls,
|
|
126
|
+
routes=merged_routes,
|
|
127
|
+
render_local_files_panel=local_files.render_panel,
|
|
128
|
+
sb_state=sb_state,
|
|
129
|
+
restore_state=local_files.restore_state,
|
|
130
|
+
)
|
|
@@ -17,7 +17,7 @@ from cjm_fasthtml_file_browser.routes.handlers import init_router as init_fb_rou
|
|
|
17
17
|
|
|
18
18
|
from cjm_fasthtml_interactions.core.state_store import get_session_id
|
|
19
19
|
|
|
20
|
-
from ..models import SelectionUrls
|
|
20
|
+
from ..models import SelectionUrls, LocalFilesResult
|
|
21
21
|
from cjm_transcript_source_select.routes.core import (
|
|
22
22
|
WorkflowStateStore, _get_step_state, _update_step_state
|
|
23
23
|
)
|
|
@@ -78,7 +78,7 @@ def init_local_files_router(
|
|
|
78
78
|
source_service: SourceService, # The source service for external db ops
|
|
79
79
|
prefix: str, # Route prefix (e.g., "/workflow/selection/local_files")
|
|
80
80
|
urls: SelectionUrls, # URL bundle for rendering
|
|
81
|
-
) ->
|
|
81
|
+
) -> LocalFilesResult: # Router result with routers, routes, render, and restore
|
|
82
82
|
"""Initialize local files browser routes with new file browser API."""
|
|
83
83
|
provider = _get_local_files_provider()
|
|
84
84
|
config = _create_db_browser_config()
|
|
@@ -90,18 +90,57 @@ def init_local_files_router(
|
|
|
90
90
|
# --- File browser state accessors (shared, non-per-session) ---
|
|
91
91
|
_browser_state = BrowserState(current_path=home_path)
|
|
92
92
|
|
|
93
|
+
# --- Lazy state restoration from persisted store ---
|
|
94
|
+
_state_restored = [False]
|
|
95
|
+
|
|
96
|
+
def _restore_from_persisted(session_id: str) -> None:
|
|
97
|
+
"""Load persisted external_db_paths and file_browser_state on first call."""
|
|
98
|
+
if _state_restored[0]:
|
|
99
|
+
return
|
|
100
|
+
step_state = _get_step_state(state_store, workflow_id, session_id)
|
|
101
|
+
|
|
102
|
+
# Restore external_db_paths
|
|
103
|
+
persisted_paths = step_state.get("external_db_paths", [])
|
|
104
|
+
if persisted_paths:
|
|
105
|
+
_external_db_paths[:] = persisted_paths
|
|
106
|
+
source_service.set_external_paths(list(_external_db_paths))
|
|
107
|
+
|
|
108
|
+
# Restore browser state (current_path, sort)
|
|
109
|
+
persisted_browser = step_state.get("file_browser_state", {})
|
|
110
|
+
if persisted_browser:
|
|
111
|
+
restored = BrowserState.from_dict(persisted_browser)
|
|
112
|
+
_browser_state.current_path = restored.current_path
|
|
113
|
+
_browser_state.sort_by = restored.sort_by
|
|
114
|
+
_browser_state.sort_descending = restored.sort_descending
|
|
115
|
+
# Selection synced from _external_db_paths via _fb_state_getter
|
|
116
|
+
|
|
117
|
+
_state_restored[0] = True
|
|
118
|
+
|
|
93
119
|
def _fb_state_getter() -> BrowserState:
|
|
94
120
|
"""Get browser state with selection synced to external_db_paths."""
|
|
95
121
|
_browser_state.selection.selected_paths = list(_external_db_paths)
|
|
96
122
|
return _browser_state
|
|
97
123
|
|
|
98
|
-
def _fb_state_setter(state: BrowserState) -> None:
|
|
99
|
-
"""Save browser state from file browser."""
|
|
124
|
+
def _fb_state_setter(state: BrowserState, request=None) -> None:
|
|
125
|
+
"""Save browser state from file browser and persist to state store."""
|
|
126
|
+
# Lazy restore on first request
|
|
127
|
+
if request is not None and not _state_restored[0]:
|
|
128
|
+
_restore_from_persisted(get_session_id(request.session))
|
|
129
|
+
|
|
100
130
|
_browser_state.current_path = state.current_path
|
|
101
131
|
_browser_state.sort_by = state.sort_by
|
|
102
132
|
_browser_state.sort_descending = state.sort_descending
|
|
103
133
|
_browser_state.selection = state.selection
|
|
104
134
|
|
|
135
|
+
# Persist browser state
|
|
136
|
+
if request is not None:
|
|
137
|
+
session_id = get_session_id(request.session)
|
|
138
|
+
_update_step_state(
|
|
139
|
+
state_store, workflow_id, session_id,
|
|
140
|
+
file_browser_state=state.to_dict(),
|
|
141
|
+
current_browse_path=state.current_path,
|
|
142
|
+
)
|
|
143
|
+
|
|
105
144
|
# --- Callbacks for file browser ---
|
|
106
145
|
def _validate_selection(path: str) -> Tuple[bool, str]:
|
|
107
146
|
"""Validate .db schema before allowing selection (checkbox click path)."""
|
|
@@ -111,8 +150,12 @@ def init_local_files_router(
|
|
|
111
150
|
return (False, error)
|
|
112
151
|
return (True, "")
|
|
113
152
|
|
|
114
|
-
def _on_selection_change(selected_paths: List[str]) -> Tuple:
|
|
153
|
+
def _on_selection_change(selected_paths: List[str], request=None) -> Tuple:
|
|
115
154
|
"""Sync external_db_paths with validation and return OOB updates."""
|
|
155
|
+
# Lazy restore on first request
|
|
156
|
+
if request is not None and not _state_restored[0]:
|
|
157
|
+
_restore_from_persisted(get_session_id(request.session))
|
|
158
|
+
|
|
116
159
|
# Validate any newly added paths
|
|
117
160
|
old_set = set(_external_db_paths)
|
|
118
161
|
validated_paths = []
|
|
@@ -134,6 +177,14 @@ def init_local_files_router(
|
|
|
134
177
|
_external_db_paths[:] = validated_paths
|
|
135
178
|
source_service.set_external_paths(list(_external_db_paths))
|
|
136
179
|
|
|
180
|
+
# Persist external_db_paths
|
|
181
|
+
if request is not None:
|
|
182
|
+
session_id = get_session_id(request.session)
|
|
183
|
+
_update_step_state(
|
|
184
|
+
state_store, workflow_id, session_id,
|
|
185
|
+
external_db_paths=list(_external_db_paths),
|
|
186
|
+
)
|
|
187
|
+
|
|
137
188
|
return (
|
|
138
189
|
_render_external_sources_list(list(_external_db_paths), urls.remove_external, oob=True),
|
|
139
190
|
_render_error_alert(error_message, oob=True),
|
|
@@ -156,8 +207,12 @@ def init_local_files_router(
|
|
|
156
207
|
)
|
|
157
208
|
|
|
158
209
|
# --- Render function for the full local files panel ---
|
|
159
|
-
def _render_panel(error_message: Optional[str] = None) -> Any:
|
|
210
|
+
def _render_panel(error_message: Optional[str] = None, session_id: Optional[str] = None) -> Any:
|
|
160
211
|
"""Render the complete local files panel (file browser + external sources list)."""
|
|
212
|
+
# Restore persisted state and rebuild items before rendering
|
|
213
|
+
if session_id is not None and not _state_restored[0]:
|
|
214
|
+
_restore_from_persisted(session_id)
|
|
215
|
+
fb_routers.sync_items()
|
|
161
216
|
return _render_local_files_browser(
|
|
162
217
|
render_fn=fb_routers.render,
|
|
163
218
|
external_paths=list(_external_db_paths),
|
|
@@ -165,6 +220,12 @@ def init_local_files_router(
|
|
|
165
220
|
error_message=error_message,
|
|
166
221
|
)
|
|
167
222
|
|
|
223
|
+
# --- Restore callable for eager state restoration ---
|
|
224
|
+
def _restore_state(session_id: str) -> None:
|
|
225
|
+
"""Restore persisted local files state (external_db_paths + browser state)."""
|
|
226
|
+
_restore_from_persisted(session_id)
|
|
227
|
+
fb_routers.sync_items()
|
|
228
|
+
|
|
168
229
|
# --- Custom router for remove_external (needs session context) ---
|
|
169
230
|
custom_router = APIRouter(prefix=prefix)
|
|
170
231
|
|
|
@@ -186,4 +247,9 @@ def init_local_files_router(
|
|
|
186
247
|
"remove_external": remove_external,
|
|
187
248
|
}
|
|
188
249
|
|
|
189
|
-
return
|
|
250
|
+
return LocalFilesResult(
|
|
251
|
+
routers=all_routers,
|
|
252
|
+
routes=routes,
|
|
253
|
+
render_panel=_render_panel,
|
|
254
|
+
restore_state=_restore_state,
|
|
255
|
+
)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
__all__ = ['init_tabs_router']
|
|
7
7
|
|
|
8
8
|
# %% ../../nbs/routes/tabs.ipynb #ca31d3ff
|
|
9
|
-
from typing import Any, Optional, Tuple, Dict, Callable
|
|
9
|
+
from typing import Any, Optional, Tuple, Dict, List, Callable
|
|
10
10
|
|
|
11
11
|
from fasthtml.common import APIRouter, Script
|
|
12
12
|
|
|
@@ -24,15 +24,16 @@ from ..services.source_utils import calculate_next_tab
|
|
|
24
24
|
|
|
25
25
|
# %% ../../nbs/routes/tabs.ipynb #4d0109d3
|
|
26
26
|
def _handle_tab_switch(
|
|
27
|
-
state_store: WorkflowStateStore, # The workflow state store
|
|
28
|
-
workflow_id: str, # The workflow identifier
|
|
29
27
|
source_service: SourceService, # The source service for queries
|
|
30
28
|
request, # FastHTML request object
|
|
31
29
|
sess, # FastHTML session object
|
|
32
30
|
direction: str, # Direction: "prev", "next", "db", or "files"
|
|
33
31
|
urls: SelectionUrls, # URL bundle for rendering
|
|
32
|
+
current_tab_ref: List[str], # Mutable ref [current_tab] for closure-based tracking
|
|
34
33
|
render_local_files_panel: Optional[Callable] = None, # Render fn for Files tab
|
|
35
34
|
sb_state: Any = None, # SourceBrowserRouterState for DB tab VC rendering
|
|
35
|
+
state_store: WorkflowStateStore = None, # State store (for reading step state)
|
|
36
|
+
workflow_id: str = "", # Workflow ID (for reading step state)
|
|
36
37
|
): # Tuple of inner content, OOB tab headers, and tab switch script
|
|
37
38
|
"""Switch between Plugin DB and Local Files tabs."""
|
|
38
39
|
session_id = get_session_id(sess)
|
|
@@ -41,14 +42,10 @@ def _handle_tab_switch(
|
|
|
41
42
|
selected_sources = step_state.get("selected_sources", [])
|
|
42
43
|
grouping_mode = step_state.get("grouping_mode", "media_path")
|
|
43
44
|
|
|
44
|
-
# Determine new tab
|
|
45
|
-
|
|
46
|
-
current_tab = workflow_state.get("source_tab", "db")
|
|
45
|
+
# Determine new tab from closure-based tracking (not persisted)
|
|
46
|
+
current_tab = current_tab_ref[0]
|
|
47
47
|
new_tab = calculate_next_tab(direction, current_tab, ["db", "files"])
|
|
48
|
-
|
|
49
|
-
# Save new tab state
|
|
50
|
-
workflow_state["source_tab"] = new_tab
|
|
51
|
-
state_store.update_state(workflow_id, session_id, workflow_state)
|
|
48
|
+
current_tab_ref[0] = new_tab
|
|
52
49
|
|
|
53
50
|
# Render the content for the new active tab
|
|
54
51
|
if new_tab == "db":
|
|
@@ -56,7 +53,7 @@ def _handle_tab_switch(
|
|
|
56
53
|
content = sb_state.rebuild_and_render(all_transcriptions, selected_sources, grouping_mode)
|
|
57
54
|
else:
|
|
58
55
|
if render_local_files_panel is not None:
|
|
59
|
-
content = render_local_files_panel()
|
|
56
|
+
content = render_local_files_panel(session_id=session_id)
|
|
60
57
|
else:
|
|
61
58
|
from cjm_transcript_source_select.components.local_files import _render_local_files_browser
|
|
62
59
|
content = _render_local_files_browser()
|
|
@@ -85,14 +82,20 @@ def init_tabs_router(
|
|
|
85
82
|
"""Initialize tab switching routes."""
|
|
86
83
|
router = APIRouter(prefix=prefix)
|
|
87
84
|
|
|
85
|
+
# Closure-based tab tracking (not persisted across restarts)
|
|
86
|
+
_current_tab: List[str] = ["db"]
|
|
87
|
+
|
|
88
88
|
@router
|
|
89
89
|
def tab_switch(request, sess, direction: str):
|
|
90
90
|
"""Switch between source tabs."""
|
|
91
91
|
return _handle_tab_switch(
|
|
92
|
-
|
|
93
|
-
request, sess, direction, urls=urls,
|
|
92
|
+
source_service=source_service,
|
|
93
|
+
request=request, sess=sess, direction=direction, urls=urls,
|
|
94
|
+
current_tab_ref=_current_tab,
|
|
94
95
|
render_local_files_panel=render_local_files_panel,
|
|
95
96
|
sb_state=sb_state,
|
|
97
|
+
state_store=state_store,
|
|
98
|
+
workflow_id=workflow_id,
|
|
96
99
|
)
|
|
97
100
|
|
|
98
101
|
routes = {
|
|
@@ -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.15
|
|
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
|
|
@@ -106,57 +106,57 @@ graph LR
|
|
|
106
106
|
utils[utils<br/>utils]
|
|
107
107
|
|
|
108
108
|
components_helpers --> models
|
|
109
|
-
components_local_files --> components_helpers
|
|
110
109
|
components_local_files --> html_ids
|
|
110
|
+
components_local_files --> components_helpers
|
|
111
111
|
components_preview_panel --> html_ids
|
|
112
112
|
components_source_browser --> services_source_utils
|
|
113
113
|
components_source_browser --> utils
|
|
114
114
|
components_source_browser --> html_ids
|
|
115
115
|
components_step_renderer --> components_preview_panel
|
|
116
|
-
components_step_renderer --> models
|
|
117
|
-
components_step_renderer --> utils
|
|
118
|
-
components_step_renderer --> components_source_browser
|
|
119
116
|
components_step_renderer --> components_selection_queue
|
|
117
|
+
components_step_renderer --> utils
|
|
120
118
|
components_step_renderer --> components_local_files
|
|
121
119
|
components_step_renderer --> html_ids
|
|
120
|
+
components_step_renderer --> models
|
|
121
|
+
components_step_renderer --> components_source_browser
|
|
122
122
|
routes_core --> models
|
|
123
|
+
routes_core --> services_source
|
|
124
|
+
routes_core --> components_selection_queue
|
|
123
125
|
routes_core --> components_step_renderer
|
|
124
126
|
routes_core --> html_ids
|
|
125
|
-
routes_core --> components_selection_queue
|
|
126
|
-
routes_core --> services_source
|
|
127
|
-
routes_filtering --> models
|
|
128
127
|
routes_filtering --> routes_core
|
|
129
128
|
routes_filtering --> services_source_utils
|
|
130
129
|
routes_filtering --> services_source
|
|
130
|
+
routes_filtering --> models
|
|
131
131
|
routes_init --> routes_core
|
|
132
132
|
routes_init --> routes_queue
|
|
133
|
-
routes_init --> models
|
|
134
|
-
routes_init --> routes_local_files
|
|
135
|
-
routes_init --> routes_source_browser
|
|
136
|
-
routes_init --> routes_filtering
|
|
137
133
|
routes_init --> routes_tabs
|
|
134
|
+
routes_init --> routes_filtering
|
|
138
135
|
routes_init --> services_source
|
|
139
|
-
|
|
136
|
+
routes_init --> routes_source_browser
|
|
137
|
+
routes_init --> routes_local_files
|
|
138
|
+
routes_init --> models
|
|
140
139
|
routes_local_files --> models
|
|
141
|
-
routes_local_files --> services_source
|
|
142
140
|
routes_local_files --> routes_core
|
|
143
|
-
|
|
141
|
+
routes_local_files --> components_local_files
|
|
142
|
+
routes_local_files --> services_source
|
|
144
143
|
routes_queue --> routes_core
|
|
144
|
+
routes_queue --> services_source_utils
|
|
145
145
|
routes_queue --> components_preview_panel
|
|
146
|
-
routes_queue --> models
|
|
147
146
|
routes_queue --> services_source
|
|
148
|
-
|
|
149
|
-
routes_source_browser --> components_preview_panel
|
|
150
|
-
routes_source_browser --> models
|
|
147
|
+
routes_queue --> models
|
|
151
148
|
routes_source_browser --> components_source_browser
|
|
149
|
+
routes_source_browser --> components_preview_panel
|
|
152
150
|
routes_source_browser --> services_source_utils
|
|
153
151
|
routes_source_browser --> services_source
|
|
152
|
+
routes_source_browser --> routes_core
|
|
154
153
|
routes_source_browser --> html_ids
|
|
155
|
-
|
|
156
|
-
routes_tabs --> services_source_utils
|
|
154
|
+
routes_source_browser --> models
|
|
157
155
|
routes_tabs --> models
|
|
158
156
|
routes_tabs --> components_step_renderer
|
|
159
157
|
routes_tabs --> services_source
|
|
158
|
+
routes_tabs --> routes_core
|
|
159
|
+
routes_tabs --> services_source_utils
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
*52 cross-module dependencies detected*
|
|
@@ -426,7 +426,7 @@ def init_selection_routers(
|
|
|
426
426
|
source_service: SourceService, # The source service for queries
|
|
427
427
|
workflow_id: str, # The workflow identifier
|
|
428
428
|
prefix: str, # Base prefix for selection routes (e.g., "/workflow/selection")
|
|
429
|
-
) ->
|
|
429
|
+
) -> SelectionResult: # Selection router result with routers, urls, routes, and restore
|
|
430
430
|
"Initialize and return all selection routers with URL bundle."
|
|
431
431
|
```
|
|
432
432
|
|
|
@@ -539,7 +539,7 @@ def init_local_files_router(
|
|
|
539
539
|
source_service: SourceService, # The source service for external db ops
|
|
540
540
|
prefix: str, # Route prefix (e.g., "/workflow/selection/local_files")
|
|
541
541
|
urls: SelectionUrls, # URL bundle for rendering
|
|
542
|
-
) ->
|
|
542
|
+
) -> LocalFilesResult: # Router result with routers, routes, render, and restore
|
|
543
543
|
"Initialize local files browser routes with new file browser API."
|
|
544
544
|
```
|
|
545
545
|
|
|
@@ -558,10 +558,24 @@ _local_files_provider: Optional[LocalFileSystemProvider] = None
|
|
|
558
558
|
``` python
|
|
559
559
|
from cjm_transcript_source_select.models import (
|
|
560
560
|
SelectionStepState,
|
|
561
|
-
SelectionUrls
|
|
561
|
+
SelectionUrls,
|
|
562
|
+
LocalFilesResult,
|
|
563
|
+
SelectionResult
|
|
562
564
|
)
|
|
563
565
|
```
|
|
564
566
|
|
|
567
|
+
#### Functions
|
|
568
|
+
|
|
569
|
+
``` python
|
|
570
|
+
def _no_op_restore(session_id: str) -> None:
|
|
571
|
+
"""Default no-op for restore_state."""
|
|
572
|
+
pass
|
|
573
|
+
|
|
574
|
+
@dataclass
|
|
575
|
+
class LocalFilesResult
|
|
576
|
+
"Default no-op for restore_state."
|
|
577
|
+
```
|
|
578
|
+
|
|
565
579
|
#### Classes
|
|
566
580
|
|
|
567
581
|
``` python
|
|
@@ -591,6 +605,30 @@ class SelectionUrls:
|
|
|
591
605
|
tab_switch: str = '' # Switch source tabs
|
|
592
606
|
```
|
|
593
607
|
|
|
608
|
+
``` python
|
|
609
|
+
@dataclass
|
|
610
|
+
class LocalFilesResult:
|
|
611
|
+
"Return type from init_local_files_router."
|
|
612
|
+
|
|
613
|
+
routers: List[APIRouter] # Routers to register (custom + file browser + VC)
|
|
614
|
+
routes: Dict[str, Callable] # Named route handlers
|
|
615
|
+
render_panel: Callable # (error_message?, session_id?) -> rendered panel
|
|
616
|
+
restore_state: Callable = field(...) # (session_id) -> None, restore persisted state
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
``` python
|
|
620
|
+
@dataclass
|
|
621
|
+
class SelectionResult:
|
|
622
|
+
"Return type from init_selection_routers."
|
|
623
|
+
|
|
624
|
+
routers: List[APIRouter] # All selection routers to register
|
|
625
|
+
urls: 'SelectionUrls' = field(...) # URL bundle
|
|
626
|
+
routes: Dict[str, Callable] = field(...) # All named route handlers
|
|
627
|
+
render_local_files_panel: Optional[Callable] # Render fn for local files tab
|
|
628
|
+
sb_state: Any # SourceBrowserRouterState
|
|
629
|
+
restore_state: Callable = field(...) # (session_id) -> None, restore persisted state
|
|
630
|
+
```
|
|
631
|
+
|
|
594
632
|
### preview_panel (`preview_panel.ipynb`)
|
|
595
633
|
|
|
596
634
|
> Collapsible preview panel for displaying selected content
|
|
@@ -1434,15 +1472,16 @@ from cjm_transcript_source_select.routes.tabs import (
|
|
|
1434
1472
|
|
|
1435
1473
|
``` python
|
|
1436
1474
|
def _handle_tab_switch(
|
|
1437
|
-
state_store: WorkflowStateStore, # The workflow state store
|
|
1438
|
-
workflow_id: str, # The workflow identifier
|
|
1439
1475
|
source_service: SourceService, # The source service for queries
|
|
1440
1476
|
request, # FastHTML request object
|
|
1441
1477
|
sess, # FastHTML session object
|
|
1442
1478
|
direction: str, # Direction: "prev", "next", "db", or "files"
|
|
1443
1479
|
urls: SelectionUrls, # URL bundle for rendering
|
|
1480
|
+
current_tab_ref: List[str], # Mutable ref [current_tab] for closure-based tracking
|
|
1444
1481
|
render_local_files_panel: Optional[Callable] = None, # Render fn for Files tab
|
|
1445
1482
|
sb_state: Any = None, # SourceBrowserRouterState for DB tab VC rendering
|
|
1483
|
+
state_store: WorkflowStateStore = None, # State store (for reading step state)
|
|
1484
|
+
workflow_id: str = "", # Workflow ID (for reading step state)
|
|
1446
1485
|
): # Tuple of inner content, OOB tab headers, and tab switch script
|
|
1447
1486
|
"Switch between Plugin DB and Local Files tabs."
|
|
1448
1487
|
```
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.14"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|