cjm-transcript-segment-align 0.0.10__tar.gz → 0.0.11__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_segment_align-0.0.10/cjm_transcript_segment_align.egg-info → cjm_transcript_segment_align-0.0.11}/PKG-INFO +16 -17
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/README.md +15 -16
- cjm_transcript_segment_align-0.0.11/cjm_transcript_segment_align/__init__.py +1 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/components/handlers.py +37 -20
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/components/step_renderer.py +36 -36
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/html_ids.py +1 -1
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/routes/chrome.py +29 -31
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11/cjm_transcript_segment_align.egg-info}/PKG-INFO +16 -17
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/settings.ini +1 -1
- cjm_transcript_segment_align-0.0.10/cjm_transcript_segment_align/__init__.py +0 -1
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/LICENSE +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/MANIFEST.in +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/_modidx.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/components/__init__.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/components/helpers.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/components/keyboard_config.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/components/sync_controls.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/components/toolbar_state.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/models.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/routes/__init__.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/routes/forced_alignment.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/routes/init.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/services/__init__.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align/services/forced_alignment.py +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align.egg-info/SOURCES.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align.egg-info/dependency_links.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align.egg-info/entry_points.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align.egg-info/not-zip-safe +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align.egg-info/requires.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/cjm_transcript_segment_align.egg-info/top_level.txt +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/pyproject.toml +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/setup.cfg +0 -0
- {cjm_transcript_segment_align-0.0.10 → cjm_transcript_segment_align-0.0.11}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: cjm-transcript-segment-align
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.11
|
|
4
4
|
Summary: FastHTML dual-column text segmentation & VAD alignment UI for transcript decomposition workflows with forced alignment-based text splitting for aligning text segments with VAD chunks.
|
|
5
5
|
Home-page: https://github.com/cj-mills/cjm-transcript-segment-align
|
|
6
6
|
Author: Christian J. Mills
|
|
@@ -83,36 +83,36 @@ graph LR
|
|
|
83
83
|
routes_init[routes.init<br/>routes/init]
|
|
84
84
|
services_forced_alignment[services.forced_alignment<br/>forced_alignment]
|
|
85
85
|
|
|
86
|
-
components_handlers -->
|
|
86
|
+
components_handlers --> components_sync_controls
|
|
87
87
|
components_handlers --> components_keyboard_config
|
|
88
|
+
components_handlers --> html_ids
|
|
88
89
|
components_handlers --> components_step_renderer
|
|
89
90
|
components_handlers --> services_forced_alignment
|
|
90
|
-
components_handlers --> components_sync_controls
|
|
91
91
|
components_handlers --> routes_forced_alignment
|
|
92
92
|
components_keyboard_config --> html_ids
|
|
93
93
|
components_keyboard_config --> components_sync_controls
|
|
94
|
+
components_step_renderer --> components_keyboard_config
|
|
95
|
+
components_step_renderer --> components_toolbar_state
|
|
94
96
|
components_step_renderer --> html_ids
|
|
95
97
|
components_step_renderer --> components_helpers
|
|
96
98
|
components_step_renderer --> components_sync_controls
|
|
97
|
-
components_step_renderer --> components_keyboard_config
|
|
98
|
-
components_step_renderer --> components_toolbar_state
|
|
99
99
|
components_toolbar_state --> components_sync_controls
|
|
100
|
-
routes_chrome --> html_ids
|
|
101
|
-
routes_chrome --> components_handlers
|
|
102
100
|
routes_chrome --> components_sync_controls
|
|
101
|
+
routes_chrome --> components_handlers
|
|
102
|
+
routes_chrome --> html_ids
|
|
103
103
|
routes_chrome --> components_step_renderer
|
|
104
|
+
routes_forced_alignment --> components_sync_controls
|
|
104
105
|
routes_forced_alignment --> html_ids
|
|
105
106
|
routes_forced_alignment --> components_step_renderer
|
|
106
|
-
routes_forced_alignment --> components_sync_controls
|
|
107
107
|
routes_init --> components_keyboard_config
|
|
108
|
-
routes_init --> html_ids
|
|
109
|
-
routes_init --> components_handlers
|
|
110
108
|
routes_init --> models
|
|
109
|
+
routes_init --> components_handlers
|
|
110
|
+
routes_init --> html_ids
|
|
111
111
|
routes_init --> services_forced_alignment
|
|
112
|
-
routes_init --> components_sync_controls
|
|
113
|
-
routes_init --> components_step_renderer
|
|
114
|
-
routes_init --> routes_forced_alignment
|
|
115
112
|
routes_init --> routes_chrome
|
|
113
|
+
routes_init --> routes_forced_alignment
|
|
114
|
+
routes_init --> components_step_renderer
|
|
115
|
+
routes_init --> components_sync_controls
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
*30 cross-module dependencies detected*
|
|
@@ -157,6 +157,7 @@ async def _handle_switch_chrome(
|
|
|
157
157
|
|
|
158
158
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
159
159
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
160
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
160
161
|
"""
|
|
161
162
|
```
|
|
162
163
|
|
|
@@ -479,9 +480,6 @@ def create_seg_mutation_wrapper(
|
|
|
479
480
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
480
481
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
481
482
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
482
|
-
|
|
483
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
484
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
485
483
|
"""
|
|
486
484
|
```
|
|
487
485
|
|
|
@@ -509,6 +507,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
509
507
|
|
|
510
508
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
511
509
|
FA controls are rendered in the toolbar via extra_actions.
|
|
510
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
512
511
|
"""
|
|
513
512
|
```
|
|
514
513
|
|
|
@@ -842,7 +841,7 @@ def _render_shared_chrome(
|
|
|
842
841
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
843
842
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
844
843
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
845
|
-
) -> tuple: # (toolbar,
|
|
844
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
846
845
|
"""
|
|
847
846
|
Render shared chrome containers, populated with segmentation content when initialized.
|
|
848
847
|
|
|
@@ -47,36 +47,36 @@ graph LR
|
|
|
47
47
|
routes_init[routes.init<br/>routes/init]
|
|
48
48
|
services_forced_alignment[services.forced_alignment<br/>forced_alignment]
|
|
49
49
|
|
|
50
|
-
components_handlers -->
|
|
50
|
+
components_handlers --> components_sync_controls
|
|
51
51
|
components_handlers --> components_keyboard_config
|
|
52
|
+
components_handlers --> html_ids
|
|
52
53
|
components_handlers --> components_step_renderer
|
|
53
54
|
components_handlers --> services_forced_alignment
|
|
54
|
-
components_handlers --> components_sync_controls
|
|
55
55
|
components_handlers --> routes_forced_alignment
|
|
56
56
|
components_keyboard_config --> html_ids
|
|
57
57
|
components_keyboard_config --> components_sync_controls
|
|
58
|
+
components_step_renderer --> components_keyboard_config
|
|
59
|
+
components_step_renderer --> components_toolbar_state
|
|
58
60
|
components_step_renderer --> html_ids
|
|
59
61
|
components_step_renderer --> components_helpers
|
|
60
62
|
components_step_renderer --> components_sync_controls
|
|
61
|
-
components_step_renderer --> components_keyboard_config
|
|
62
|
-
components_step_renderer --> components_toolbar_state
|
|
63
63
|
components_toolbar_state --> components_sync_controls
|
|
64
|
-
routes_chrome --> html_ids
|
|
65
|
-
routes_chrome --> components_handlers
|
|
66
64
|
routes_chrome --> components_sync_controls
|
|
65
|
+
routes_chrome --> components_handlers
|
|
66
|
+
routes_chrome --> html_ids
|
|
67
67
|
routes_chrome --> components_step_renderer
|
|
68
|
+
routes_forced_alignment --> components_sync_controls
|
|
68
69
|
routes_forced_alignment --> html_ids
|
|
69
70
|
routes_forced_alignment --> components_step_renderer
|
|
70
|
-
routes_forced_alignment --> components_sync_controls
|
|
71
71
|
routes_init --> components_keyboard_config
|
|
72
|
-
routes_init --> html_ids
|
|
73
|
-
routes_init --> components_handlers
|
|
74
72
|
routes_init --> models
|
|
73
|
+
routes_init --> components_handlers
|
|
74
|
+
routes_init --> html_ids
|
|
75
75
|
routes_init --> services_forced_alignment
|
|
76
|
-
routes_init --> components_sync_controls
|
|
77
|
-
routes_init --> components_step_renderer
|
|
78
|
-
routes_init --> routes_forced_alignment
|
|
79
76
|
routes_init --> routes_chrome
|
|
77
|
+
routes_init --> routes_forced_alignment
|
|
78
|
+
routes_init --> components_step_renderer
|
|
79
|
+
routes_init --> components_sync_controls
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
*30 cross-module dependencies detected*
|
|
@@ -121,6 +121,7 @@ async def _handle_switch_chrome(
|
|
|
121
121
|
|
|
122
122
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
123
123
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
124
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
124
125
|
"""
|
|
125
126
|
```
|
|
126
127
|
|
|
@@ -443,9 +444,6 @@ def create_seg_mutation_wrapper(
|
|
|
443
444
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
444
445
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
445
446
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
446
|
-
|
|
447
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
448
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
449
447
|
"""
|
|
450
448
|
```
|
|
451
449
|
|
|
@@ -473,6 +471,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
473
471
|
|
|
474
472
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
475
473
|
FA controls are rendered in the toolbar via extra_actions.
|
|
474
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
476
475
|
"""
|
|
477
476
|
```
|
|
478
477
|
|
|
@@ -806,7 +805,7 @@ def _render_shared_chrome(
|
|
|
806
805
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
807
806
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
808
807
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
809
|
-
) -> tuple: # (toolbar,
|
|
808
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
810
809
|
"""
|
|
811
810
|
Render shared chrome containers, populated with segmentation content when initialized.
|
|
812
811
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.11"
|
|
@@ -16,10 +16,12 @@ from typing import Callable, Any, Dict, List, Optional, Tuple
|
|
|
16
16
|
from fasthtml.common import Div, Span, Button, FT
|
|
17
17
|
|
|
18
18
|
from cjm_fasthtml_interactions.core.state_store import get_session_id
|
|
19
|
-
from cjm_fasthtml_card_stack.components.
|
|
19
|
+
from cjm_fasthtml_card_stack.components.settings_modal import render_card_stack_settings_modal, render_settings_trigger
|
|
20
20
|
from cjm_fasthtml_card_stack.core.constants import DEFAULT_VISIBLE_COUNT
|
|
21
21
|
from cjm_fasthtml_daisyui.components.data_display.badge import badge, badge_styles, badge_sizes
|
|
22
|
+
from cjm_fasthtml_tailwind.utilities.sizing import w
|
|
22
23
|
from cjm_fasthtml_tailwind.utilities.layout import display_tw
|
|
24
|
+
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import flex_display, items, gap
|
|
23
25
|
from cjm_fasthtml_tailwind.core.base import combine_classes
|
|
24
26
|
|
|
25
27
|
from ..html_ids import CombinedHtmlIds
|
|
@@ -277,9 +279,6 @@ def create_seg_mutation_wrapper(
|
|
|
277
279
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
278
280
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
279
281
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
280
|
-
|
|
281
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
282
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
283
282
|
"""
|
|
284
283
|
@wraps(handler_result)
|
|
285
284
|
async def wrapped(
|
|
@@ -333,7 +332,7 @@ def create_seg_mutation_wrapper(
|
|
|
333
332
|
urls = kwargs.get("urls")
|
|
334
333
|
seg_oob = build_mutation_response(
|
|
335
334
|
result.segment_dicts, result.focused_index, result.visible_count,
|
|
336
|
-
result.history_depth, urls,
|
|
335
|
+
result.history_depth, urls,
|
|
337
336
|
extra_actions=build_extra_actions(fa_extra), nltk_split_disabled=nltk_disabled,
|
|
338
337
|
)
|
|
339
338
|
|
|
@@ -341,7 +340,6 @@ def create_seg_mutation_wrapper(
|
|
|
341
340
|
|
|
342
341
|
return wrapped
|
|
343
342
|
|
|
344
|
-
|
|
345
343
|
# %% ../../nbs/components/handlers.ipynb #f6a7b8c9
|
|
346
344
|
def wrap_align_mutation_handler(
|
|
347
345
|
handler: Callable, # Handler function to wrap
|
|
@@ -388,6 +386,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
388
386
|
|
|
389
387
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
390
388
|
FA controls are rendered in the toolbar via extra_actions.
|
|
389
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
391
390
|
"""
|
|
392
391
|
async def wrapped_seg_init(
|
|
393
392
|
state_store:WorkflowStateStore,
|
|
@@ -455,24 +454,43 @@ def create_seg_init_chrome_wrapper(
|
|
|
455
454
|
seg_state, jm_trigger, fa_toggle_url, fa_available,
|
|
456
455
|
)
|
|
457
456
|
|
|
458
|
-
#
|
|
457
|
+
# Settings modal trigger for seg column
|
|
458
|
+
settings_trigger = render_settings_trigger(modal_id=SEG_CS_IDS.settings_modal)
|
|
459
|
+
|
|
460
|
+
# Toolbar OOB (settings trigger + toolbar with FA controls, NLTK Split disabled at init)
|
|
459
461
|
toolbar_oob = Div(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
462
|
+
Div(
|
|
463
|
+
settings_trigger,
|
|
464
|
+
render_toolbar(
|
|
465
|
+
reset_url=urls.reset, ai_split_url=urls.ai_split, undo_url=urls.undo,
|
|
466
|
+
can_undo=(result.history_depth > 0),
|
|
467
|
+
extra_actions=build_extra_actions(fa_extra),
|
|
468
|
+
nltk_split_disabled=True,
|
|
469
|
+
),
|
|
470
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
467
471
|
),
|
|
468
472
|
id=CombinedHtmlIds.SHARED_TOOLBAR,
|
|
469
473
|
hx_swap_oob="innerHTML"
|
|
470
474
|
)
|
|
471
475
|
|
|
472
|
-
#
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
+
# Settings modals OOB (both seg + align persist in DOM)
|
|
477
|
+
from cjm_transcript_vad_align.components.card_stack_config import (
|
|
478
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
479
|
+
)
|
|
480
|
+
seg_modal, _ = render_card_stack_settings_modal(
|
|
481
|
+
SEG_CS_CONFIG, SEG_CS_IDS,
|
|
482
|
+
current_count=result.visible_count,
|
|
483
|
+
card_width=result.card_width,
|
|
484
|
+
)
|
|
485
|
+
align_modal, _ = render_card_stack_settings_modal(
|
|
486
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
487
|
+
current_count=align_state.get("visible_count", 5),
|
|
488
|
+
card_width=align_state.get("card_width", 40),
|
|
489
|
+
)
|
|
490
|
+
settings_modals_oob = Div(
|
|
491
|
+
seg_modal,
|
|
492
|
+
align_modal,
|
|
493
|
+
id=CombinedHtmlIds.SETTINGS_MODALS,
|
|
476
494
|
hx_swap_oob="innerHTML"
|
|
477
495
|
)
|
|
478
496
|
|
|
@@ -499,12 +517,11 @@ def create_seg_init_chrome_wrapper(
|
|
|
499
517
|
|
|
500
518
|
return (
|
|
501
519
|
result.column_body, kb_system_oob, zone_change_js, chrome_switch_btn,
|
|
502
|
-
toolbar_oob,
|
|
520
|
+
toolbar_oob, settings_modals_oob, footer_oob, mini_stats_oob,
|
|
503
521
|
)
|
|
504
522
|
|
|
505
523
|
return wrapped_seg_init
|
|
506
524
|
|
|
507
|
-
|
|
508
525
|
# %% ../../nbs/components/handlers.ipynb #ecvyiypdxk
|
|
509
526
|
def create_align_init_chrome_wrapper(
|
|
510
527
|
should_play_fn:str="", # Consumer-defined play guard function name
|
|
@@ -35,8 +35,8 @@ from cjm_fasthtml_tailwind.core.base import combine_classes
|
|
|
35
35
|
from cjm_fasthtml_interactions.core.context import InteractionContext
|
|
36
36
|
|
|
37
37
|
# Card stack library
|
|
38
|
-
from cjm_fasthtml_card_stack.components.controls import render_width_slider
|
|
39
38
|
from cjm_fasthtml_card_stack.components.states import render_loading_state
|
|
39
|
+
from cjm_fasthtml_card_stack.components.settings_modal import render_card_stack_settings_modal
|
|
40
40
|
from cjm_fasthtml_card_stack.core.constants import DEFAULT_VISIBLE_COUNT, DEFAULT_CARD_WIDTH
|
|
41
41
|
|
|
42
42
|
# Local imports
|
|
@@ -63,7 +63,7 @@ from cjm_transcript_vad_align.components.step_renderer import (
|
|
|
63
63
|
render_align_footer_content,
|
|
64
64
|
)
|
|
65
65
|
from cjm_transcript_vad_align.components.card_stack_config import (
|
|
66
|
-
ALIGN_CS_IDS,
|
|
66
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
67
67
|
)
|
|
68
68
|
|
|
69
69
|
# Shared keyboard config (combined-level)
|
|
@@ -88,7 +88,6 @@ from .toolbar_state import generate_toolbar_restore_js
|
|
|
88
88
|
# Debug flag for combined step rendering tracing (set False in production)
|
|
89
89
|
DEBUG_COMBINED_RENDER = True
|
|
90
90
|
|
|
91
|
-
|
|
92
91
|
# %% ../../nbs/components/step_renderer.ipynb #e5f6a7b8
|
|
93
92
|
def _render_column_header(
|
|
94
93
|
title:str, # Column title (e.g., "Text Decomposition")
|
|
@@ -227,7 +226,7 @@ def _render_shared_chrome(
|
|
|
227
226
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
228
227
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
229
228
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
230
|
-
) -> tuple: # (toolbar,
|
|
229
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
231
230
|
"""Render shared chrome containers, populated with segmentation content when initialized.
|
|
232
231
|
|
|
233
232
|
Takes extracted state dicts from `extract_seg_state()` and `extract_alignment_state()`
|
|
@@ -235,19 +234,37 @@ def _render_shared_chrome(
|
|
|
235
234
|
"""
|
|
236
235
|
is_init = seg_state is not None and seg_state.get("is_initialized", False)
|
|
237
236
|
|
|
237
|
+
# --- Settings modals (both persist in DOM, triggers swap with toolbar) ---
|
|
238
|
+
seg_modal, seg_trigger = render_card_stack_settings_modal(
|
|
239
|
+
SEG_CS_CONFIG, SEG_CS_IDS,
|
|
240
|
+
current_count=seg_state.get("visible_count", DEFAULT_VISIBLE_COUNT) if seg_state else DEFAULT_VISIBLE_COUNT,
|
|
241
|
+
card_width=seg_state.get("card_width", DEFAULT_CARD_WIDTH) if seg_state else DEFAULT_CARD_WIDTH,
|
|
242
|
+
)
|
|
243
|
+
align_modal, align_trigger = render_card_stack_settings_modal(
|
|
244
|
+
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
245
|
+
current_count=align_state.get("visible_count", 5) if align_state else 5,
|
|
246
|
+
card_width=align_state.get("card_width", 40) if align_state else 40,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
settings_modals_container = Div(
|
|
250
|
+
seg_modal,
|
|
251
|
+
align_modal,
|
|
252
|
+
id=CombinedHtmlIds.SETTINGS_MODALS,
|
|
253
|
+
)
|
|
254
|
+
|
|
238
255
|
# --- Toolbar ---
|
|
239
256
|
if is_init and urls:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
257
|
+
toolbar_content = Div(
|
|
258
|
+
seg_trigger,
|
|
259
|
+
render_toolbar(
|
|
260
|
+
reset_url=urls.reset,
|
|
261
|
+
ai_split_url=urls.ai_split,
|
|
262
|
+
undo_url=urls.undo,
|
|
263
|
+
can_undo=(len(seg_state.get("history", [])) > 0),
|
|
264
|
+
extra_actions=extra_actions,
|
|
265
|
+
nltk_split_disabled=nltk_split_disabled,
|
|
266
|
+
),
|
|
267
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
251
268
|
)
|
|
252
269
|
else:
|
|
253
270
|
toolbar_content = _placeholder("Toolbar actions will appear here based on the active column.")
|
|
@@ -258,22 +275,7 @@ def _render_shared_chrome(
|
|
|
258
275
|
cls=str(p(2))
|
|
259
276
|
)
|
|
260
277
|
|
|
261
|
-
# --- Controls ---
|
|
262
|
-
if is_init:
|
|
263
|
-
card_width = seg_state.get("card_width", DEFAULT_CARD_WIDTH)
|
|
264
|
-
controls_content = render_width_slider(SEG_CS_CONFIG, SEG_CS_IDS, card_width=card_width)
|
|
265
|
-
else:
|
|
266
|
-
controls_content = _placeholder("Column-specific controls will appear here.")
|
|
267
|
-
|
|
268
|
-
controls = Div(
|
|
269
|
-
controls_content,
|
|
270
|
-
id=CombinedHtmlIds.SHARED_CONTROLS,
|
|
271
|
-
cls=str(p(2))
|
|
272
|
-
)
|
|
273
|
-
|
|
274
278
|
# --- Footer with both column footers + alignment status ---
|
|
275
|
-
# Note: seg_state["segments"] and align_state["vad_chunks"] are already deserialized
|
|
276
|
-
# objects from extract_seg_state/extract_alignment_state — don't call from_dict() again
|
|
277
279
|
seg_segments = seg_state.get("segments", []) if seg_state else []
|
|
278
280
|
segment_count = len(seg_segments)
|
|
279
281
|
align_chunks = align_state.get("vad_chunks", []) if align_state else []
|
|
@@ -306,8 +308,7 @@ def _render_shared_chrome(
|
|
|
306
308
|
)
|
|
307
309
|
)
|
|
308
310
|
|
|
309
|
-
return toolbar,
|
|
310
|
-
|
|
311
|
+
return toolbar, footer, settings_modals_container
|
|
311
312
|
|
|
312
313
|
# %% ../../nbs/components/step_renderer.ipynb #c9d0e1f2
|
|
313
314
|
# Shared column styling (reused by init handler for outerHTML swap)
|
|
@@ -528,7 +529,7 @@ def render_combined_step(
|
|
|
528
529
|
)
|
|
529
530
|
mini_stats_text = render_seg_mini_stats_text(segments)
|
|
530
531
|
|
|
531
|
-
toolbar,
|
|
532
|
+
toolbar, footer, settings_modals_container = _render_shared_chrome(
|
|
532
533
|
seg_state=seg_state,
|
|
533
534
|
align_state=align_state,
|
|
534
535
|
urls=seg_urls,
|
|
@@ -542,7 +543,7 @@ def render_combined_step(
|
|
|
542
543
|
mini_stats_text=mini_stats_text,
|
|
543
544
|
)
|
|
544
545
|
else:
|
|
545
|
-
toolbar,
|
|
546
|
+
toolbar, footer, settings_modals_container = _render_shared_chrome(
|
|
546
547
|
align_state=align_state,
|
|
547
548
|
)
|
|
548
549
|
seg_col = _render_seg_column(
|
|
@@ -630,7 +631,6 @@ def render_combined_step(
|
|
|
630
631
|
cls=combine_classes(flex_display, items.start, justify.between),
|
|
631
632
|
),
|
|
632
633
|
toolbar,
|
|
633
|
-
controls,
|
|
634
634
|
Div(
|
|
635
635
|
*columns_children,
|
|
636
636
|
id=CombinedHtmlIds.COLUMNS,
|
|
@@ -649,6 +649,7 @@ def render_combined_step(
|
|
|
649
649
|
toolbar_restore_script,
|
|
650
650
|
chrome_switch_btn,
|
|
651
651
|
active_column_input,
|
|
652
|
+
settings_modals_container, # Both settings modals persist in DOM
|
|
652
653
|
jm_modal_el, # Job monitor modal (page-level, outside columns)
|
|
653
654
|
jm_kb_script_el, # Job monitor keyboard script placeholder (for OOB pause/resume)
|
|
654
655
|
hints_modal, # Keyboard hints modal dialog
|
|
@@ -660,4 +661,3 @@ def render_combined_step(
|
|
|
660
661
|
p(4), p.x(2), p.b(0)
|
|
661
662
|
)
|
|
662
663
|
)
|
|
663
|
-
|
|
@@ -21,9 +21,9 @@ class CombinedHtmlIds:
|
|
|
21
21
|
# Shared Chrome
|
|
22
22
|
SHARED_HINTS = "sd-shared-hints"
|
|
23
23
|
SHARED_TOOLBAR = "sd-shared-toolbar"
|
|
24
|
-
SHARED_CONTROLS = "sd-shared-controls"
|
|
25
24
|
SHARED_FOOTER = "sd-shared-footer"
|
|
26
25
|
ALIGNMENT_STATUS = "sd-alignment-status"
|
|
26
|
+
SETTINGS_MODALS = "sd-settings-modals"
|
|
27
27
|
|
|
28
28
|
# Segmentation Column
|
|
29
29
|
SEG_COLUMN = "sd-seg-column"
|
|
@@ -10,7 +10,7 @@ from typing import Tuple, Dict, Callable
|
|
|
10
10
|
|
|
11
11
|
from fasthtml.common import APIRouter, Div
|
|
12
12
|
|
|
13
|
-
from cjm_fasthtml_card_stack.components.
|
|
13
|
+
from cjm_fasthtml_card_stack.components.settings_modal import render_settings_trigger
|
|
14
14
|
from cjm_fasthtml_card_stack.core.constants import DEFAULT_VISIBLE_COUNT, DEFAULT_CARD_WIDTH
|
|
15
15
|
|
|
16
16
|
from cjm_fasthtml_interactions.core.state_store import get_session_id
|
|
@@ -38,6 +38,12 @@ from cjm_transcript_vad_align.components.card_stack_config import (
|
|
|
38
38
|
ALIGN_CS_CONFIG, ALIGN_CS_IDS,
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
+
from cjm_fasthtml_tailwind.utilities.sizing import w
|
|
42
|
+
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import (
|
|
43
|
+
flex_display, items, gap,
|
|
44
|
+
)
|
|
45
|
+
from cjm_fasthtml_tailwind.core.base import combine_classes
|
|
46
|
+
|
|
41
47
|
# Footer helper + FA extra_actions builder + match detection
|
|
42
48
|
from cjm_transcript_segment_align.components.step_renderer import (
|
|
43
49
|
render_footer_inner_content,
|
|
@@ -66,6 +72,7 @@ async def _handle_switch_chrome(
|
|
|
66
72
|
|
|
67
73
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
68
74
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
75
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
69
76
|
"""
|
|
70
77
|
form = await request.form()
|
|
71
78
|
active_column = form.get("active_column", "seg")
|
|
@@ -84,13 +91,10 @@ async def _handle_switch_chrome(
|
|
|
84
91
|
chunk_count = len(align_state.get("vad_chunks", []))
|
|
85
92
|
|
|
86
93
|
if active_column == "seg":
|
|
87
|
-
# Segmentation chrome (
|
|
94
|
+
# Segmentation chrome (settings trigger + toolbar)
|
|
88
95
|
segments = [TextSegment.from_dict(s) for s in seg_state.get("segments", [])]
|
|
89
96
|
history = seg_state.get("history", [])
|
|
90
97
|
focused_index = seg_state.get("focused_index", 0)
|
|
91
|
-
visible_count = seg_state.get("visible_count", DEFAULT_VISIBLE_COUNT)
|
|
92
|
-
is_auto_mode = seg_state.get("is_auto_mode", False)
|
|
93
|
-
card_width = seg_state.get("card_width", DEFAULT_CARD_WIDTH)
|
|
94
98
|
|
|
95
99
|
# Build FA extra_actions and NLTK Split disabled state
|
|
96
100
|
fa_extra = build_fa_extra_actions(
|
|
@@ -101,28 +105,27 @@ async def _handle_switch_chrome(
|
|
|
101
105
|
seg_state.get("segments", []), nltk_presplit,
|
|
102
106
|
)
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
settings_trigger = render_settings_trigger(modal_id=SEG_CS_IDS.settings_modal)
|
|
109
|
+
toolbar_content = Div(
|
|
110
|
+
settings_trigger,
|
|
111
|
+
render_seg_toolbar(
|
|
112
|
+
reset_url=seg_urls.reset,
|
|
113
|
+
ai_split_url=seg_urls.ai_split,
|
|
114
|
+
undo_url=seg_urls.undo,
|
|
115
|
+
can_undo=(len(history) > 0),
|
|
116
|
+
extra_actions=build_extra_actions(fa_extra),
|
|
117
|
+
nltk_split_disabled=nltk_disabled,
|
|
118
|
+
),
|
|
119
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
113
120
|
)
|
|
114
|
-
controls_content = render_width_slider(SEG_CS_CONFIG, SEG_CS_IDS, card_width=card_width)
|
|
115
121
|
else:
|
|
116
|
-
# Alignment chrome (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
visible_count=visible_count,
|
|
123
|
-
is_auto_mode=is_auto_mode,
|
|
122
|
+
# Alignment chrome (settings trigger + auto-play toggle)
|
|
123
|
+
settings_trigger = render_settings_trigger(modal_id=ALIGN_CS_IDS.settings_modal)
|
|
124
|
+
toolbar_content = Div(
|
|
125
|
+
settings_trigger,
|
|
126
|
+
render_align_toolbar(),
|
|
127
|
+
cls=combine_classes(flex_display, items.center, gap(2), w.full),
|
|
124
128
|
)
|
|
125
|
-
controls_content = render_width_slider(ALIGN_CS_CONFIG, ALIGN_CS_IDS, card_width=card_width)
|
|
126
129
|
|
|
127
130
|
# --- Footer: both column footers always present ---
|
|
128
131
|
seg_segments = [TextSegment.from_dict(s) for s in seg_state.get("segments", [])]
|
|
@@ -136,24 +139,19 @@ async def _handle_switch_chrome(
|
|
|
136
139
|
if DEBUG_SWITCH_CHROME:
|
|
137
140
|
print(f"[SWITCH_CHROME] returning OOB swaps for {active_column}")
|
|
138
141
|
|
|
139
|
-
# Return OOB swaps
|
|
142
|
+
# Return OOB swaps (toolbar + footer — settings modals persist in DOM)
|
|
140
143
|
toolbar_oob = Div(
|
|
141
144
|
toolbar_content,
|
|
142
145
|
id=CombinedHtmlIds.SHARED_TOOLBAR,
|
|
143
146
|
hx_swap_oob="innerHTML"
|
|
144
147
|
)
|
|
145
|
-
controls_oob = Div(
|
|
146
|
-
controls_content,
|
|
147
|
-
id=CombinedHtmlIds.SHARED_CONTROLS,
|
|
148
|
-
hx_swap_oob="innerHTML"
|
|
149
|
-
)
|
|
150
148
|
footer_oob = Div(
|
|
151
149
|
render_footer_inner_content(seg_footer, align_footer, segment_count, chunk_count),
|
|
152
150
|
id=CombinedHtmlIds.SHARED_FOOTER,
|
|
153
151
|
hx_swap_oob="innerHTML"
|
|
154
152
|
)
|
|
155
153
|
|
|
156
|
-
return (toolbar_oob,
|
|
154
|
+
return (toolbar_oob, footer_oob)
|
|
157
155
|
|
|
158
156
|
# %% ../../nbs/routes/chrome.ipynb #g7b8c9d0
|
|
159
157
|
def init_chrome_router(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: cjm-transcript-segment-align
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.11
|
|
4
4
|
Summary: FastHTML dual-column text segmentation & VAD alignment UI for transcript decomposition workflows with forced alignment-based text splitting for aligning text segments with VAD chunks.
|
|
5
5
|
Home-page: https://github.com/cj-mills/cjm-transcript-segment-align
|
|
6
6
|
Author: Christian J. Mills
|
|
@@ -83,36 +83,36 @@ graph LR
|
|
|
83
83
|
routes_init[routes.init<br/>routes/init]
|
|
84
84
|
services_forced_alignment[services.forced_alignment<br/>forced_alignment]
|
|
85
85
|
|
|
86
|
-
components_handlers -->
|
|
86
|
+
components_handlers --> components_sync_controls
|
|
87
87
|
components_handlers --> components_keyboard_config
|
|
88
|
+
components_handlers --> html_ids
|
|
88
89
|
components_handlers --> components_step_renderer
|
|
89
90
|
components_handlers --> services_forced_alignment
|
|
90
|
-
components_handlers --> components_sync_controls
|
|
91
91
|
components_handlers --> routes_forced_alignment
|
|
92
92
|
components_keyboard_config --> html_ids
|
|
93
93
|
components_keyboard_config --> components_sync_controls
|
|
94
|
+
components_step_renderer --> components_keyboard_config
|
|
95
|
+
components_step_renderer --> components_toolbar_state
|
|
94
96
|
components_step_renderer --> html_ids
|
|
95
97
|
components_step_renderer --> components_helpers
|
|
96
98
|
components_step_renderer --> components_sync_controls
|
|
97
|
-
components_step_renderer --> components_keyboard_config
|
|
98
|
-
components_step_renderer --> components_toolbar_state
|
|
99
99
|
components_toolbar_state --> components_sync_controls
|
|
100
|
-
routes_chrome --> html_ids
|
|
101
|
-
routes_chrome --> components_handlers
|
|
102
100
|
routes_chrome --> components_sync_controls
|
|
101
|
+
routes_chrome --> components_handlers
|
|
102
|
+
routes_chrome --> html_ids
|
|
103
103
|
routes_chrome --> components_step_renderer
|
|
104
|
+
routes_forced_alignment --> components_sync_controls
|
|
104
105
|
routes_forced_alignment --> html_ids
|
|
105
106
|
routes_forced_alignment --> components_step_renderer
|
|
106
|
-
routes_forced_alignment --> components_sync_controls
|
|
107
107
|
routes_init --> components_keyboard_config
|
|
108
|
-
routes_init --> html_ids
|
|
109
|
-
routes_init --> components_handlers
|
|
110
108
|
routes_init --> models
|
|
109
|
+
routes_init --> components_handlers
|
|
110
|
+
routes_init --> html_ids
|
|
111
111
|
routes_init --> services_forced_alignment
|
|
112
|
-
routes_init --> components_sync_controls
|
|
113
|
-
routes_init --> components_step_renderer
|
|
114
|
-
routes_init --> routes_forced_alignment
|
|
115
112
|
routes_init --> routes_chrome
|
|
113
|
+
routes_init --> routes_forced_alignment
|
|
114
|
+
routes_init --> components_step_renderer
|
|
115
|
+
routes_init --> components_sync_controls
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
*30 cross-module dependencies detected*
|
|
@@ -157,6 +157,7 @@ async def _handle_switch_chrome(
|
|
|
157
157
|
|
|
158
158
|
Client-side toolbar state restoration (sync button, auto-play toggle)
|
|
159
159
|
is handled by the centralized settle handler from toolbar_state.py.
|
|
160
|
+
Settings modals persist in the DOM — only the trigger buttons swap.
|
|
160
161
|
"""
|
|
161
162
|
```
|
|
162
163
|
|
|
@@ -479,9 +480,6 @@ def create_seg_mutation_wrapper(
|
|
|
479
480
|
Calls the _result handler variant, builds targeted OOB response with FA
|
|
480
481
|
controls in toolbar, and appends alignment status + mini-stats OOB.
|
|
481
482
|
Computes nltk_split_disabled from state for toolbar rendering.
|
|
482
|
-
|
|
483
|
-
When clear_fa_presplit=True (used for NLTK Split), clears the FA pre-split
|
|
484
|
-
snapshot so the toggle is replaced with the Force Align button.
|
|
485
483
|
"""
|
|
486
484
|
```
|
|
487
485
|
|
|
@@ -509,6 +507,7 @@ def create_seg_init_chrome_wrapper(
|
|
|
509
507
|
|
|
510
508
|
Saves nltk_presplit snapshot at init time for match detection.
|
|
511
509
|
FA controls are rendered in the toolbar via extra_actions.
|
|
510
|
+
Settings modals are rendered in a persistent container (both seg + align).
|
|
512
511
|
"""
|
|
513
512
|
```
|
|
514
513
|
|
|
@@ -842,7 +841,7 @@ def _render_shared_chrome(
|
|
|
842
841
|
urls:SegmentationUrls=None, # Segmentation URL bundle (required when seg_state provided)
|
|
843
842
|
extra_actions:tuple=(), # Extra toolbar elements (FA controls, sync toggle, etc.)
|
|
844
843
|
nltk_split_disabled:bool=False, # Whether NLTK Split button is disabled
|
|
845
|
-
) -> tuple: # (toolbar,
|
|
844
|
+
) -> tuple: # (toolbar, footer, settings_modals_container)
|
|
846
845
|
"""
|
|
847
846
|
Render shared chrome containers, populated with segmentation content when initialized.
|
|
848
847
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.10"
|
|
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
|