Spaces:
Paused
Paused
Update app.py via AI Editor
Browse files
app.py
CHANGED
@@ -219,9 +219,6 @@ def get_left_col_content():
|
|
219 |
)
|
220 |
return [
|
221 |
html.H4("Proposal Writer", className="mt-3 mb-2", style={'marginBottom': '12px'}),
|
222 |
-
html.Div([
|
223 |
-
html.Div(className="blinking-dot", style={'margin':'0 auto','width':'16px','height':'16px'}),
|
224 |
-
], style={'textAlign':'center', 'marginBottom':'10px'}),
|
225 |
html.Hr(style={'marginTop': '8px', 'marginBottom': '16px'}),
|
226 |
html.Div(
|
227 |
id='doc-type-buttons'
|
@@ -231,9 +228,6 @@ def get_left_col_content():
|
|
231 |
|
232 |
def get_right_col_content(selected_type, store_data):
|
233 |
controls = []
|
234 |
-
controls.append(html.Div([
|
235 |
-
html.Div(className="blinking-dot", style={'margin':'0 auto','width':'16px','height':'16px'}),
|
236 |
-
], style={'textAlign':'center', 'marginBottom':'10px'}))
|
237 |
controls.append(dcc.Loading(
|
238 |
id="loading-indicator",
|
239 |
type="dot",
|
@@ -351,6 +345,7 @@ app.layout = dbc.Container([
|
|
351 |
dcc.Store(id='store-loe'),
|
352 |
dcc.Store(id='store-virtual-board'),
|
353 |
dcc.Store(id='store-generated-doc'),
|
|
|
354 |
dbc.Row([
|
355 |
dbc.Col(
|
356 |
html.H2(id='main-title', className="mt-3 mb-2", style={'textAlign': 'center', 'width':'100%'}),
|
@@ -359,9 +354,13 @@ app.layout = dbc.Container([
|
|
359 |
]),
|
360 |
dbc.Row([
|
361 |
dbc.Col(
|
362 |
-
|
363 |
-
|
364 |
-
|
|
|
|
|
|
|
|
|
365 |
)
|
366 |
]),
|
367 |
dbc.Row([
|
@@ -456,7 +455,8 @@ def update_right_col(selected_type, shred, pink, pink_review, red, red_review, g
|
|
456 |
[
|
457 |
Output('store-shred', 'data'),
|
458 |
Output('file-list', 'children'),
|
459 |
-
Output('uploaded-doc-name-shred', 'children')
|
|
|
460 |
],
|
461 |
[
|
462 |
Input({'type': 'upload-doc-type', 'subtype': 'shred', 'index': 'Shred'}, 'contents')
|
@@ -493,18 +493,19 @@ def handle_shred_upload(contents, filenames, current_shred, file_list):
|
|
493 |
], id={'type': 'file-row', 'index': name}, align="center", className="mb-1")
|
494 |
)
|
495 |
logging.info("Shred document uploaded and stored.")
|
496 |
-
return latest_text, file_previews, filenames[-1]
|
497 |
|
498 |
@app.callback(
|
499 |
Output('store-pink', 'data'),
|
500 |
Output('uploaded-doc-name-pink', 'children'),
|
|
|
501 |
Input({'type': 'upload-doc-type', 'subtype': 'pink', 'index': ALL}, 'contents'),
|
502 |
State({'type': 'upload-doc-type', 'subtype': 'pink', 'index': ALL}, 'filename'),
|
503 |
prevent_initial_call=True
|
504 |
)
|
505 |
def handle_pink_upload(contents_list, filenames_list):
|
506 |
if not contents_list or not filenames_list:
|
507 |
-
return dash.no_update, dash.no_update
|
508 |
for contents, filenames in zip(contents_list, filenames_list):
|
509 |
if contents and filenames:
|
510 |
if isinstance(contents, str):
|
@@ -512,19 +513,20 @@ def handle_pink_upload(contents_list, filenames_list):
|
|
512 |
filenames = [filenames]
|
513 |
for content, name in zip(contents, filenames):
|
514 |
file_text = process_document(content, name)
|
515 |
-
return file_text, name
|
516 |
-
return dash.no_update, dash.no_update
|
517 |
|
518 |
@app.callback(
|
519 |
Output('store-pink-review', 'data'),
|
520 |
Output('uploaded-doc-name-pink_review', 'children'),
|
|
|
521 |
Input({'type': 'upload-doc-type', 'subtype': 'pink_review', 'index': ALL}, 'contents'),
|
522 |
State({'type': 'upload-doc-type', 'subtype': 'pink_review', 'index': ALL}, 'filename'),
|
523 |
prevent_initial_call=True
|
524 |
)
|
525 |
def handle_pink_review_upload(contents_list, filenames_list):
|
526 |
if not contents_list or not filenames_list:
|
527 |
-
return dash.no_update, dash.no_update
|
528 |
for contents, filenames in zip(contents_list, filenames_list):
|
529 |
if contents and filenames:
|
530 |
if isinstance(contents, str):
|
@@ -532,19 +534,20 @@ def handle_pink_review_upload(contents_list, filenames_list):
|
|
532 |
filenames = [filenames]
|
533 |
for content, name in zip(contents, filenames):
|
534 |
file_text = process_document(content, name)
|
535 |
-
return file_text, name
|
536 |
-
return dash.no_update, dash.no_update
|
537 |
|
538 |
@app.callback(
|
539 |
Output('store-red', 'data'),
|
540 |
Output('uploaded-doc-name-red', 'children'),
|
|
|
541 |
Input({'type': 'upload-doc-type', 'subtype': 'red', 'index': ALL}, 'contents'),
|
542 |
State({'type': 'upload-doc-type', 'subtype': 'red', 'index': ALL}, 'filename'),
|
543 |
prevent_initial_call=True
|
544 |
)
|
545 |
def handle_red_upload(contents_list, filenames_list):
|
546 |
if not contents_list or not filenames_list:
|
547 |
-
return dash.no_update, dash.no_update
|
548 |
for contents, filenames in zip(contents_list, filenames_list):
|
549 |
if contents and filenames:
|
550 |
if isinstance(contents, str):
|
@@ -552,19 +555,20 @@ def handle_red_upload(contents_list, filenames_list):
|
|
552 |
filenames = [filenames]
|
553 |
for content, name in zip(contents, filenames):
|
554 |
file_text = process_document(content, name)
|
555 |
-
return file_text, name
|
556 |
-
return dash.no_update, dash.no_update
|
557 |
|
558 |
@app.callback(
|
559 |
Output('store-red-review', 'data'),
|
560 |
Output('uploaded-doc-name-red_review', 'children'),
|
|
|
561 |
Input({'type': 'upload-doc-type', 'subtype': 'red_review', 'index': ALL}, 'contents'),
|
562 |
State({'type': 'upload-doc-type', 'subtype': 'red_review', 'index': ALL}, 'filename'),
|
563 |
prevent_initial_call=True
|
564 |
)
|
565 |
def handle_red_review_upload(contents_list, filenames_list):
|
566 |
if not contents_list or not filenames_list:
|
567 |
-
return dash.no_update, dash.no_update
|
568 |
for contents, filenames in zip(contents_list, filenames_list):
|
569 |
if contents and filenames:
|
570 |
if isinstance(contents, str):
|
@@ -572,19 +576,20 @@ def handle_red_review_upload(contents_list, filenames_list):
|
|
572 |
filenames = [filenames]
|
573 |
for content, name in zip(contents, filenames):
|
574 |
file_text = process_document(content, name)
|
575 |
-
return file_text, name
|
576 |
-
return dash.no_update, dash.no_update
|
577 |
|
578 |
@app.callback(
|
579 |
Output('store-gold', 'data'),
|
580 |
Output('uploaded-doc-name-gold', 'children'),
|
|
|
581 |
Input({'type': 'upload-doc-type', 'subtype': 'gold', 'index': ALL}, 'contents'),
|
582 |
State({'type': 'upload-doc-type', 'subtype': 'gold', 'index': ALL}, 'filename'),
|
583 |
prevent_initial_call=True
|
584 |
)
|
585 |
def handle_gold_upload(contents_list, filenames_list):
|
586 |
if not contents_list or not filenames_list:
|
587 |
-
return dash.no_update, dash.no_update
|
588 |
for contents, filenames in zip(contents_list, filenames_list):
|
589 |
if contents and filenames:
|
590 |
if isinstance(contents, str):
|
@@ -592,19 +597,20 @@ def handle_gold_upload(contents_list, filenames_list):
|
|
592 |
filenames = [filenames]
|
593 |
for content, name in zip(contents, filenames):
|
594 |
file_text = process_document(content, name)
|
595 |
-
return file_text, name
|
596 |
-
return dash.no_update, dash.no_update
|
597 |
|
598 |
@app.callback(
|
599 |
Output('store-gold-review', 'data'),
|
600 |
Output('uploaded-doc-name-gold_review', 'children'),
|
|
|
601 |
Input({'type': 'upload-doc-type', 'subtype': 'gold_review', 'index': ALL}, 'contents'),
|
602 |
State({'type': 'upload-doc-type', 'subtype': 'gold_review', 'index': ALL}, 'filename'),
|
603 |
prevent_initial_call=True
|
604 |
)
|
605 |
def handle_gold_review_upload(contents_list, filenames_list):
|
606 |
if not contents_list or not filenames_list:
|
607 |
-
return dash.no_update, dash.no_update
|
608 |
for contents, filenames in zip(contents_list, filenames_list):
|
609 |
if contents and filenames:
|
610 |
if isinstance(contents, str):
|
@@ -612,19 +618,20 @@ def handle_gold_review_upload(contents_list, filenames_list):
|
|
612 |
filenames = [filenames]
|
613 |
for content, name in zip(contents, filenames):
|
614 |
file_text = process_document(content, name)
|
615 |
-
return file_text, name
|
616 |
-
return dash.no_update, dash.no_update
|
617 |
|
618 |
@app.callback(
|
619 |
Output('store-loe', 'data'),
|
620 |
Output('uploaded-doc-name-loe', 'children'),
|
|
|
621 |
Input({'type': 'upload-doc-type', 'subtype': 'loe', 'index': ALL}, 'contents'),
|
622 |
State({'type': 'upload-doc-type', 'subtype': 'loe', 'index': ALL}, 'filename'),
|
623 |
prevent_initial_call=True
|
624 |
)
|
625 |
def handle_loe_upload(contents_list, filenames_list):
|
626 |
if not contents_list or not filenames_list:
|
627 |
-
return dash.no_update, dash.no_update
|
628 |
for contents, filenames in zip(contents_list, filenames_list):
|
629 |
if contents and filenames:
|
630 |
if isinstance(contents, str):
|
@@ -632,19 +639,20 @@ def handle_loe_upload(contents_list, filenames_list):
|
|
632 |
filenames = [filenames]
|
633 |
for content, name in zip(contents, filenames):
|
634 |
file_text = process_document(content, name)
|
635 |
-
return file_text, name
|
636 |
-
return dash.no_update, dash.no_update
|
637 |
|
638 |
@app.callback(
|
639 |
Output('store-virtual-board', 'data'),
|
640 |
Output('uploaded-doc-name-virtual_board', 'children'),
|
|
|
641 |
Input({'type': 'upload-doc-type', 'subtype': 'virtual_board', 'index': ALL}, 'contents'),
|
642 |
State({'type': 'upload-doc-type', 'subtype': 'virtual_board', 'index': ALL}, 'filename'),
|
643 |
prevent_initial_call=True
|
644 |
)
|
645 |
def handle_virtual_board_upload(contents_list, filenames_list):
|
646 |
if not contents_list or not filenames_list:
|
647 |
-
return dash.no_update, dash.no_update
|
648 |
for contents, filenames in zip(contents_list, filenames_list):
|
649 |
if contents and filenames:
|
650 |
if isinstance(contents, str):
|
@@ -652,11 +660,12 @@ def handle_virtual_board_upload(contents_list, filenames_list):
|
|
652 |
filenames = [filenames]
|
653 |
for content, name in zip(contents, filenames):
|
654 |
file_text = process_document(content, name)
|
655 |
-
return file_text, name
|
656 |
-
return dash.no_update, dash.no_update
|
657 |
|
658 |
@app.callback(
|
659 |
Output('document-preview', 'children'),
|
|
|
660 |
[
|
661 |
Input({'type': 'btn-generate-doc', 'index': ALL}, 'n_clicks'),
|
662 |
Input('selected-doc-type', 'data'),
|
@@ -718,10 +727,10 @@ def preview_or_generate_doc(n_clicks_list, selected_type, shred, pink, pink_revi
|
|
718 |
else:
|
719 |
preview = markdown_narrative_preview(generated_doc)
|
720 |
logging.info("Document preview updated.")
|
721 |
-
return preview
|
722 |
else:
|
723 |
if selected_type == "Shred" and shred:
|
724 |
-
return markdown_table_preview(shred)
|
725 |
elif selected_type in spreadsheet_types:
|
726 |
doc_store = {
|
727 |
"Pink Review": pink_review,
|
@@ -731,7 +740,7 @@ def preview_or_generate_doc(n_clicks_list, selected_type, shred, pink, pink_revi
|
|
731 |
"LOE": loe
|
732 |
}
|
733 |
doc = doc_store.get(selected_type, "")
|
734 |
-
return markdown_table_preview(doc)
|
735 |
elif selected_type in narrative_types:
|
736 |
doc_store = {
|
737 |
"Pink": pink,
|
@@ -739,11 +748,12 @@ def preview_or_generate_doc(n_clicks_list, selected_type, shred, pink, pink_revi
|
|
739 |
"Gold": gold
|
740 |
}
|
741 |
doc = doc_store.get(selected_type, "")
|
742 |
-
return markdown_narrative_preview(doc)
|
743 |
-
return html.Div("No document loaded.")
|
744 |
|
745 |
@app.callback(
|
746 |
Output('store-generated-doc', 'data'),
|
|
|
747 |
[
|
748 |
Input({'type': 'btn-generate-doc', 'index': ALL}, 'n_clicks'),
|
749 |
Input('selected-doc-type', 'data'),
|
@@ -767,11 +777,12 @@ def update_generated_doc(n_clicks_list, selected_type, preview_content, shred, p
|
|
767 |
ctx = callback_context
|
768 |
trigger = ctx.triggered[0]['prop_id'] if ctx.triggered else ""
|
769 |
if any(n_clicks_list):
|
770 |
-
return app.server.config.get('last_generated_doc', prev_generated)
|
771 |
-
return prev_generated
|
772 |
|
773 |
@app.callback(
|
774 |
Output("download-document", "data"),
|
|
|
775 |
Input("btn-download", "n_clicks"),
|
776 |
State('selected-doc-type', 'data'),
|
777 |
State('store-generated-doc', 'data'),
|
@@ -809,15 +820,23 @@ def download_document(n_clicks, selected_type, generated_doc, shred, pink, pink_
|
|
809 |
doc = virtual_board
|
810 |
if not doc:
|
811 |
logging.warning("No generated document to download.")
|
812 |
-
return dash.no_update
|
813 |
if selected_type in spreadsheet_types:
|
814 |
xlsx_io = markdown_tables_to_xlsx(doc)
|
815 |
logging.info("Spreadsheet document prepared for download.")
|
816 |
-
return dcc.send_bytes(xlsx_io.getvalue(), filename=f"{selected_type}_output.xlsx")
|
817 |
else:
|
818 |
content = doc.encode('utf-8')
|
819 |
logging.info("Narrative document prepared for download.")
|
820 |
-
return dcc.send_bytes(content, filename=f"{selected_type}_output.md")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
821 |
|
822 |
if __name__ == '__main__':
|
823 |
print("Starting the Dash application...")
|
|
|
219 |
)
|
220 |
return [
|
221 |
html.H4("Proposal Writer", className="mt-3 mb-2", style={'marginBottom': '12px'}),
|
|
|
|
|
|
|
222 |
html.Hr(style={'marginTop': '8px', 'marginBottom': '16px'}),
|
223 |
html.Div(
|
224 |
id='doc-type-buttons'
|
|
|
228 |
|
229 |
def get_right_col_content(selected_type, store_data):
|
230 |
controls = []
|
|
|
|
|
|
|
231 |
controls.append(dcc.Loading(
|
232 |
id="loading-indicator",
|
233 |
type="dot",
|
|
|
345 |
dcc.Store(id='store-loe'),
|
346 |
dcc.Store(id='store-virtual-board'),
|
347 |
dcc.Store(id='store-generated-doc'),
|
348 |
+
dcc.Store(id='progress-dot-store'),
|
349 |
dbc.Row([
|
350 |
dbc.Col(
|
351 |
html.H2(id='main-title', className="mt-3 mb-2", style={'textAlign': 'center', 'width':'100%'}),
|
|
|
354 |
]),
|
355 |
dbc.Row([
|
356 |
dbc.Col(
|
357 |
+
dcc.Loading(
|
358 |
+
id="main-progress-dot",
|
359 |
+
type="dot",
|
360 |
+
children=html.Div(id="main-progress-dot-output")
|
361 |
+
),
|
362 |
+
width=12,
|
363 |
+
style={'textAlign':'center', 'marginBottom':'10px'}
|
364 |
)
|
365 |
]),
|
366 |
dbc.Row([
|
|
|
455 |
[
|
456 |
Output('store-shred', 'data'),
|
457 |
Output('file-list', 'children'),
|
458 |
+
Output('uploaded-doc-name-shred', 'children'),
|
459 |
+
Output('progress-dot-store', 'data')
|
460 |
],
|
461 |
[
|
462 |
Input({'type': 'upload-doc-type', 'subtype': 'shred', 'index': 'Shred'}, 'contents')
|
|
|
493 |
], id={'type': 'file-row', 'index': name}, align="center", className="mb-1")
|
494 |
)
|
495 |
logging.info("Shred document uploaded and stored.")
|
496 |
+
return latest_text, file_previews, filenames[-1], "progress"
|
497 |
|
498 |
@app.callback(
|
499 |
Output('store-pink', 'data'),
|
500 |
Output('uploaded-doc-name-pink', 'children'),
|
501 |
+
Output('progress-dot-store', 'data'),
|
502 |
Input({'type': 'upload-doc-type', 'subtype': 'pink', 'index': ALL}, 'contents'),
|
503 |
State({'type': 'upload-doc-type', 'subtype': 'pink', 'index': ALL}, 'filename'),
|
504 |
prevent_initial_call=True
|
505 |
)
|
506 |
def handle_pink_upload(contents_list, filenames_list):
|
507 |
if not contents_list or not filenames_list:
|
508 |
+
return dash.no_update, dash.no_update, dash.no_update
|
509 |
for contents, filenames in zip(contents_list, filenames_list):
|
510 |
if contents and filenames:
|
511 |
if isinstance(contents, str):
|
|
|
513 |
filenames = [filenames]
|
514 |
for content, name in zip(contents, filenames):
|
515 |
file_text = process_document(content, name)
|
516 |
+
return file_text, name, "progress"
|
517 |
+
return dash.no_update, dash.no_update, dash.no_update
|
518 |
|
519 |
@app.callback(
|
520 |
Output('store-pink-review', 'data'),
|
521 |
Output('uploaded-doc-name-pink_review', 'children'),
|
522 |
+
Output('progress-dot-store', 'data'),
|
523 |
Input({'type': 'upload-doc-type', 'subtype': 'pink_review', 'index': ALL}, 'contents'),
|
524 |
State({'type': 'upload-doc-type', 'subtype': 'pink_review', 'index': ALL}, 'filename'),
|
525 |
prevent_initial_call=True
|
526 |
)
|
527 |
def handle_pink_review_upload(contents_list, filenames_list):
|
528 |
if not contents_list or not filenames_list:
|
529 |
+
return dash.no_update, dash.no_update, dash.no_update
|
530 |
for contents, filenames in zip(contents_list, filenames_list):
|
531 |
if contents and filenames:
|
532 |
if isinstance(contents, str):
|
|
|
534 |
filenames = [filenames]
|
535 |
for content, name in zip(contents, filenames):
|
536 |
file_text = process_document(content, name)
|
537 |
+
return file_text, name, "progress"
|
538 |
+
return dash.no_update, dash.no_update, dash.no_update
|
539 |
|
540 |
@app.callback(
|
541 |
Output('store-red', 'data'),
|
542 |
Output('uploaded-doc-name-red', 'children'),
|
543 |
+
Output('progress-dot-store', 'data'),
|
544 |
Input({'type': 'upload-doc-type', 'subtype': 'red', 'index': ALL}, 'contents'),
|
545 |
State({'type': 'upload-doc-type', 'subtype': 'red', 'index': ALL}, 'filename'),
|
546 |
prevent_initial_call=True
|
547 |
)
|
548 |
def handle_red_upload(contents_list, filenames_list):
|
549 |
if not contents_list or not filenames_list:
|
550 |
+
return dash.no_update, dash.no_update, dash.no_update
|
551 |
for contents, filenames in zip(contents_list, filenames_list):
|
552 |
if contents and filenames:
|
553 |
if isinstance(contents, str):
|
|
|
555 |
filenames = [filenames]
|
556 |
for content, name in zip(contents, filenames):
|
557 |
file_text = process_document(content, name)
|
558 |
+
return file_text, name, "progress"
|
559 |
+
return dash.no_update, dash.no_update, dash.no_update
|
560 |
|
561 |
@app.callback(
|
562 |
Output('store-red-review', 'data'),
|
563 |
Output('uploaded-doc-name-red_review', 'children'),
|
564 |
+
Output('progress-dot-store', 'data'),
|
565 |
Input({'type': 'upload-doc-type', 'subtype': 'red_review', 'index': ALL}, 'contents'),
|
566 |
State({'type': 'upload-doc-type', 'subtype': 'red_review', 'index': ALL}, 'filename'),
|
567 |
prevent_initial_call=True
|
568 |
)
|
569 |
def handle_red_review_upload(contents_list, filenames_list):
|
570 |
if not contents_list or not filenames_list:
|
571 |
+
return dash.no_update, dash.no_update, dash.no_update
|
572 |
for contents, filenames in zip(contents_list, filenames_list):
|
573 |
if contents and filenames:
|
574 |
if isinstance(contents, str):
|
|
|
576 |
filenames = [filenames]
|
577 |
for content, name in zip(contents, filenames):
|
578 |
file_text = process_document(content, name)
|
579 |
+
return file_text, name, "progress"
|
580 |
+
return dash.no_update, dash.no_update, dash.no_update
|
581 |
|
582 |
@app.callback(
|
583 |
Output('store-gold', 'data'),
|
584 |
Output('uploaded-doc-name-gold', 'children'),
|
585 |
+
Output('progress-dot-store', 'data'),
|
586 |
Input({'type': 'upload-doc-type', 'subtype': 'gold', 'index': ALL}, 'contents'),
|
587 |
State({'type': 'upload-doc-type', 'subtype': 'gold', 'index': ALL}, 'filename'),
|
588 |
prevent_initial_call=True
|
589 |
)
|
590 |
def handle_gold_upload(contents_list, filenames_list):
|
591 |
if not contents_list or not filenames_list:
|
592 |
+
return dash.no_update, dash.no_update, dash.no_update
|
593 |
for contents, filenames in zip(contents_list, filenames_list):
|
594 |
if contents and filenames:
|
595 |
if isinstance(contents, str):
|
|
|
597 |
filenames = [filenames]
|
598 |
for content, name in zip(contents, filenames):
|
599 |
file_text = process_document(content, name)
|
600 |
+
return file_text, name, "progress"
|
601 |
+
return dash.no_update, dash.no_update, dash.no_update
|
602 |
|
603 |
@app.callback(
|
604 |
Output('store-gold-review', 'data'),
|
605 |
Output('uploaded-doc-name-gold_review', 'children'),
|
606 |
+
Output('progress-dot-store', 'data'),
|
607 |
Input({'type': 'upload-doc-type', 'subtype': 'gold_review', 'index': ALL}, 'contents'),
|
608 |
State({'type': 'upload-doc-type', 'subtype': 'gold_review', 'index': ALL}, 'filename'),
|
609 |
prevent_initial_call=True
|
610 |
)
|
611 |
def handle_gold_review_upload(contents_list, filenames_list):
|
612 |
if not contents_list or not filenames_list:
|
613 |
+
return dash.no_update, dash.no_update, dash.no_update
|
614 |
for contents, filenames in zip(contents_list, filenames_list):
|
615 |
if contents and filenames:
|
616 |
if isinstance(contents, str):
|
|
|
618 |
filenames = [filenames]
|
619 |
for content, name in zip(contents, filenames):
|
620 |
file_text = process_document(content, name)
|
621 |
+
return file_text, name, "progress"
|
622 |
+
return dash.no_update, dash.no_update, dash.no_update
|
623 |
|
624 |
@app.callback(
|
625 |
Output('store-loe', 'data'),
|
626 |
Output('uploaded-doc-name-loe', 'children'),
|
627 |
+
Output('progress-dot-store', 'data'),
|
628 |
Input({'type': 'upload-doc-type', 'subtype': 'loe', 'index': ALL}, 'contents'),
|
629 |
State({'type': 'upload-doc-type', 'subtype': 'loe', 'index': ALL}, 'filename'),
|
630 |
prevent_initial_call=True
|
631 |
)
|
632 |
def handle_loe_upload(contents_list, filenames_list):
|
633 |
if not contents_list or not filenames_list:
|
634 |
+
return dash.no_update, dash.no_update, dash.no_update
|
635 |
for contents, filenames in zip(contents_list, filenames_list):
|
636 |
if contents and filenames:
|
637 |
if isinstance(contents, str):
|
|
|
639 |
filenames = [filenames]
|
640 |
for content, name in zip(contents, filenames):
|
641 |
file_text = process_document(content, name)
|
642 |
+
return file_text, name, "progress"
|
643 |
+
return dash.no_update, dash.no_update, dash.no_update
|
644 |
|
645 |
@app.callback(
|
646 |
Output('store-virtual-board', 'data'),
|
647 |
Output('uploaded-doc-name-virtual_board', 'children'),
|
648 |
+
Output('progress-dot-store', 'data'),
|
649 |
Input({'type': 'upload-doc-type', 'subtype': 'virtual_board', 'index': ALL}, 'contents'),
|
650 |
State({'type': 'upload-doc-type', 'subtype': 'virtual_board', 'index': ALL}, 'filename'),
|
651 |
prevent_initial_call=True
|
652 |
)
|
653 |
def handle_virtual_board_upload(contents_list, filenames_list):
|
654 |
if not contents_list or not filenames_list:
|
655 |
+
return dash.no_update, dash.no_update, dash.no_update
|
656 |
for contents, filenames in zip(contents_list, filenames_list):
|
657 |
if contents and filenames:
|
658 |
if isinstance(contents, str):
|
|
|
660 |
filenames = [filenames]
|
661 |
for content, name in zip(contents, filenames):
|
662 |
file_text = process_document(content, name)
|
663 |
+
return file_text, name, "progress"
|
664 |
+
return dash.no_update, dash.no_update, dash.no_update
|
665 |
|
666 |
@app.callback(
|
667 |
Output('document-preview', 'children'),
|
668 |
+
Output('progress-dot-store', 'data'),
|
669 |
[
|
670 |
Input({'type': 'btn-generate-doc', 'index': ALL}, 'n_clicks'),
|
671 |
Input('selected-doc-type', 'data'),
|
|
|
727 |
else:
|
728 |
preview = markdown_narrative_preview(generated_doc)
|
729 |
logging.info("Document preview updated.")
|
730 |
+
return preview, "progress"
|
731 |
else:
|
732 |
if selected_type == "Shred" and shred:
|
733 |
+
return markdown_table_preview(shred), dash.no_update
|
734 |
elif selected_type in spreadsheet_types:
|
735 |
doc_store = {
|
736 |
"Pink Review": pink_review,
|
|
|
740 |
"LOE": loe
|
741 |
}
|
742 |
doc = doc_store.get(selected_type, "")
|
743 |
+
return markdown_table_preview(doc), dash.no_update
|
744 |
elif selected_type in narrative_types:
|
745 |
doc_store = {
|
746 |
"Pink": pink,
|
|
|
748 |
"Gold": gold
|
749 |
}
|
750 |
doc = doc_store.get(selected_type, "")
|
751 |
+
return markdown_narrative_preview(doc), dash.no_update
|
752 |
+
return html.Div("No document loaded."), dash.no_update
|
753 |
|
754 |
@app.callback(
|
755 |
Output('store-generated-doc', 'data'),
|
756 |
+
Output('progress-dot-store', 'data'),
|
757 |
[
|
758 |
Input({'type': 'btn-generate-doc', 'index': ALL}, 'n_clicks'),
|
759 |
Input('selected-doc-type', 'data'),
|
|
|
777 |
ctx = callback_context
|
778 |
trigger = ctx.triggered[0]['prop_id'] if ctx.triggered else ""
|
779 |
if any(n_clicks_list):
|
780 |
+
return app.server.config.get('last_generated_doc', prev_generated), "progress"
|
781 |
+
return prev_generated, dash.no_update
|
782 |
|
783 |
@app.callback(
|
784 |
Output("download-document", "data"),
|
785 |
+
Output('progress-dot-store', 'data'),
|
786 |
Input("btn-download", "n_clicks"),
|
787 |
State('selected-doc-type', 'data'),
|
788 |
State('store-generated-doc', 'data'),
|
|
|
820 |
doc = virtual_board
|
821 |
if not doc:
|
822 |
logging.warning("No generated document to download.")
|
823 |
+
return dash.no_update, dash.no_update
|
824 |
if selected_type in spreadsheet_types:
|
825 |
xlsx_io = markdown_tables_to_xlsx(doc)
|
826 |
logging.info("Spreadsheet document prepared for download.")
|
827 |
+
return dcc.send_bytes(xlsx_io.getvalue(), filename=f"{selected_type}_output.xlsx"), "progress"
|
828 |
else:
|
829 |
content = doc.encode('utf-8')
|
830 |
logging.info("Narrative document prepared for download.")
|
831 |
+
return dcc.send_bytes(content, filename=f"{selected_type}_output.md"), "progress"
|
832 |
+
|
833 |
+
@app.callback(
|
834 |
+
Output("main-progress-dot-output", "children"),
|
835 |
+
Input('progress-dot-store', 'data')
|
836 |
+
)
|
837 |
+
def update_main_progress_dot(progress):
|
838 |
+
# Dummy output to trigger dcc.Loading
|
839 |
+
return ""
|
840 |
|
841 |
if __name__ == '__main__':
|
842 |
print("Starting the Dash application...")
|