From ca0e5a6ff45a08ecfc989338aa4eb353acdbcbb1 Mon Sep 17 00:00:00 2001 From: George Earl Date: Tue, 5 Mar 2024 13:38:37 +0000 Subject: [PATCH 1/6] Remove unused variable in Utilities class --- functions/shared_code/utilities.py | 1 - 1 file changed, 1 deletion(-) diff --git a/functions/shared_code/utilities.py b/functions/shared_code/utilities.py index 45adfd7a7..f2f20171e 100644 --- a/functions/shared_code/utilities.py +++ b/functions/shared_code/utilities.py @@ -446,7 +446,6 @@ def build_chunks(self, document_map, myblob_name, myblob_uri, chunk_target_size) previous_subtitle_name = document_map['structure'][0]["subtitle"] page_list = [] chunk_count = 0 - previous_paragraph_element_is_a_table = False # iterate over the paragraphs and build a chuck based on a section # and/or title of the document From 3c0bb8e51c37b821c998df9bf07cc2369a76f1d7 Mon Sep 17 00:00:00 2001 From: George Earl Date: Tue, 5 Mar 2024 13:46:34 +0000 Subject: [PATCH 2/6] Add check for previous paragraph element being a table --- functions/shared_code/utilities.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/functions/shared_code/utilities.py b/functions/shared_code/utilities.py index f2f20171e..14537787d 100644 --- a/functions/shared_code/utilities.py +++ b/functions/shared_code/utilities.py @@ -446,7 +446,8 @@ def build_chunks(self, document_map, myblob_name, myblob_uri, chunk_target_size) previous_subtitle_name = document_map['structure'][0]["subtitle"] page_list = [] chunk_count = 0 - + previous_paragraph_element_is_a_table = False + # iterate over the paragraphs and build a chuck based on a section # and/or title of the document for index, paragraph_element in enumerate(document_map['structure']): From ba86193e89e0e05a7c961c2c89b933fa37fac8a5 Mon Sep 17 00:00:00 2001 From: George Earl Date: Tue, 5 Mar 2024 13:48:50 +0000 Subject: [PATCH 3/6] Remove unused variable in utilities.py --- functions/shared_code/utilities.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/functions/shared_code/utilities.py b/functions/shared_code/utilities.py index 14537787d..28c84506a 100644 --- a/functions/shared_code/utilities.py +++ b/functions/shared_code/utilities.py @@ -446,8 +446,7 @@ def build_chunks(self, document_map, myblob_name, myblob_uri, chunk_target_size) previous_subtitle_name = document_map['structure'][0]["subtitle"] page_list = [] chunk_count = 0 - previous_paragraph_element_is_a_table = False - + # iterate over the paragraphs and build a chuck based on a section # and/or title of the document for index, paragraph_element in enumerate(document_map['structure']): From fe5b0d75cd024b5aba9afcb267ec7a6cccd0ffeb Mon Sep 17 00:00:00 2001 From: dayland Date: Wed, 6 Mar 2024 12:49:22 +0000 Subject: [PATCH 4/6] Add new variable and update file upload status model --- app/backend/app.py | 8 +- app/frontend/src/api/models.ts | 7 ++ .../FileStatus/DocumentsDetailList.module.css | 6 + .../FileStatus/DocumentsDetailList.tsx | 118 +++++++++++++++--- .../src/components/FileStatus/FileStatus.tsx | 5 + functions/shared_code/utilities.py | 3 +- 6 files changed, 126 insertions(+), 21 deletions(-) diff --git a/app/backend/app.py b/app/backend/app.py index c43474fab..10ceae898 100644 --- a/app/backend/app.py +++ b/app/backend/app.py @@ -22,7 +22,7 @@ ResourceTypes, generate_account_sas, ) -from shared_code.status_log import State, StatusClassification, StatusLog +from shared_code.status_log import State, StatusClassification, StatusLog, StatusQueryLevel from shared_code.tags_helper import TagsHelper from azure.cosmos import CosmosClient @@ -279,8 +279,10 @@ async def get_all_upload_status(request: Request): state = json_body.get("state") folder = json_body.get("folder") try: - results = statusLog.read_files_status_by_timeframe(timeframe, State[state], - folder, os.environ["AZURE_BLOB_STORAGE_UPLOAD_CONTAINER"]) + results = statusLog.read_files_status_by_timeframe(timeframe, + State[state], + folder, + os.environ["AZURE_BLOB_STORAGE_UPLOAD_CONTAINER"]) # retrieve tags for each file # Initialize an empty list to hold the tags diff --git a/app/frontend/src/api/models.ts b/app/frontend/src/api/models.ts index 25e7ef512..0630e4cb7 100644 --- a/app/frontend/src/api/models.ts +++ b/app/frontend/src/api/models.ts @@ -69,6 +69,13 @@ export type FileUploadBasicStatus = { start_timestamp: string; state_description: string; state_timestamp: string; + status_updates: StatusUpdates[]; +} + +export type StatusUpdates = { + status: string; + status_timestamp: string; + status_classification: string; } export type AllFilesUploadStatus = { diff --git a/app/frontend/src/components/FileStatus/DocumentsDetailList.module.css b/app/frontend/src/components/FileStatus/DocumentsDetailList.module.css index 5b22e548e..9ee042eb8 100644 --- a/app/frontend/src/components/FileStatus/DocumentsDetailList.module.css +++ b/app/frontend/src/components/FileStatus/DocumentsDetailList.module.css @@ -64,3 +64,9 @@ text-overflow: clip; /* Clip text that overflows */ white-space: normal; /* Allow text to wrap */ } + +.scrollableDialogContent { + max-height: 400px; /* Adjust the height as needed */ + max-width: 400px; /* Adjust the width as needed */ + overflow-y: auto; /* This enables vertical scrolling */ +} \ No newline at end of file diff --git a/app/frontend/src/components/FileStatus/DocumentsDetailList.tsx b/app/frontend/src/components/FileStatus/DocumentsDetailList.tsx index 93d698b4d..d14c6a160 100644 --- a/app/frontend/src/components/FileStatus/DocumentsDetailList.tsx +++ b/app/frontend/src/components/FileStatus/DocumentsDetailList.tsx @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useEffect, useRef, useLayoutEffect } from "react"; import { DetailsList, DetailsListLayoutMode, SelectionMode, @@ -30,6 +30,11 @@ export interface IDocument { state_description: string; upload_timestamp: string; modified_timestamp: string; + status_updates: Array<{ + status: string; + status_timestamp: string; + status_classification: string; + }>; isSelected?: boolean; // Optional property to track selection state } @@ -139,19 +144,19 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => { // ************************************************************* // Delete processing // New state for managing dialog visibility and selected items - const [isDialogVisible, setIsDialogVisible] = useState(false); + const [isDeleteDialogVisible, setIsDeleteDialogVisible] = useState(false); const [selectedItemsForDeletion, setSelectedItemsForDeletion] = useState([]); // Function to open the dialog with selected items const showDeleteConfirmation = () => { const selectedItems = selectionRef.current.getSelection() as IDocument[]; setSelectedItemsForDeletion(selectedItems); - setIsDialogVisible(true); + setIsDeleteDialogVisible(true); }; // Function to handle actual deletion const handleDelete = () => { - setIsDialogVisible(false); + setIsDeleteDialogVisible(false); console.log("Items to delete:", selectedItemsForDeletion); selectedItemsForDeletion.forEach(item => { console.log(`Deleting item: ${item.name}`); @@ -207,7 +212,60 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => { showResubmitConfirmation(); }; - + // ******************************************************************** + // State detail dialog + const [stateDialogVisible, setStateDialogVisible] = useState(false); + const [stateDialogContent, setStateDialogContent] = useState(null); + const scrollableContentRef = useRef(null); + + // const onStateColumnClick = async (item: IDocument) => { + // try { + // //const text = await getTextForState(item); + // // const text = item.status_updates[0].status; + // const text = item.status_updates.map(update => update.status).join("\n"); + // setStateDialogContent(text); + // setStateDialogVisible(true); + // } catch (error) { + // console.error("Error on state column click:", error); + // // Handle error here, perhaps show an error message to the user + // } + // }; + + + const onStateColumnClick = (item: IDocument) => { + try { + const statusElements = item.status_updates.map((update, index) => ( +
+ {update.status_timestamp} - {update.status} +
+ )); + setStateDialogContent(statusElements); + setStateDialogVisible(true); + } catch (error) { + console.error("Error on state column click:", error); + // Handle error here, perhaps show an error message to the user + } + }; + + + const dialogStyles = { + main: { + width: '400px', // Set the width to 400 pixels + maxWidth: '400px', // Set the maximum width to 400 pixels + maxHeight: '400px', // Set the maximum height to 400 pixels + overflowY: 'auto', // Enable vertical scrolling for the entire dialog if needed + }, + }; + + + useEffect(() => { + // Scroll to the top when the dialog opens + window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); + }, []); + + // ******************************************************************** + + const [columns, setColumns] = useState ([ { key: 'file_type', @@ -251,11 +309,13 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => { ariaLabel: 'Column operations for state, Press to sort by states', onColumnClick: onColumnClick, data: 'string', - onRender: (item: IDocument) => ( - - {item.state} - {item.state === 'Error' && retryErroredFile(item)}> - Retry File} - + onRender: (item: IDocument) => ( + + onStateColumnClick(item)} style={{ cursor: 'pointer' }}> + {item.state} + + {item.state === 'Error' && retryErroredFile(item)}> - Retry File} + ), isPadded: true, }, @@ -269,9 +329,12 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => { ariaLabel: 'Column operations for folder, Press to sort by folder', onColumnClick: onColumnClick, data: 'string', - onRender: (item: IDocument) => { - return {item.filePath}; - }, + onRender: (item: IDocument) => ( + + {item.filePath.split('/').slice(1, -1).join('/')} + {item.filePath === 'Error' && retryErroredFile(item)}> Retry File} + + ), isPadded: true, }, { @@ -322,7 +385,9 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => { onColumnClick: onColumnClick, onRender: (item: IDocument) => ( - {item.state} + onStateColumnClick(item)} style={{ cursor: 'pointer' }}> + {item.state_description} + ) } @@ -348,8 +413,8 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => {