Skip to content

Commit

Permalink
Merge pull request #535 from microsoft/wotey/status
Browse files Browse the repository at this point in the history
addition off Status component and new Panel for Status log
  • Loading branch information
wotey committed Mar 6, 2024
2 parents 59c7304 + d3175a2 commit 09d73bb
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 19 deletions.
17 changes: 10 additions & 7 deletions app/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,32 @@
"watch": "tsc && vite build --watch"
},
"dependencies": {
"@azure/storage-blob": "^12.13.0",
"@fluentui/react": "^8.110.7",
"@fluentui/react-icons": "^2.0.195",
"@react-spring/web": "^9.7.1",
"dompurify": "^3.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.1",
"@azure/storage-blob": "^12.13.0",
"classnames": "^2.3.1",
"dompurify": "^3.0.1",
"nanoid": "3.3.4",
"prop-types": "15.8.1",
"react": "^18.2.0",
"react-bootstrap": "^2.7.4",
"react-dom": "^18.2.0",
"react-draggable": "^4.4.6",
"react-markdown": "^9.0.1",
"react-router-dom": "^6.8.1",
"react-table": "^7.8.0",
"remark-gfm": "^3.0.0"
},
"devDependencies": {
"@types/dompurify": "^2.4.0",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@types/react-resizable": "^3.0.7",
"@vitejs/plugin-react": "^4.2.1",
"postcss-nesting": "^11.2.2",
"prettier": "^2.8.3",
"typescript": "^4.9.3",
"vite": "^5.0.10",
"postcss-nesting": "^11.2.2"
"vite": "^5.0.10"
}
}
58 changes: 46 additions & 12 deletions app/frontend/src/components/FileStatus/DocumentsDetailList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ import { DetailsList,
DialogType,
DialogFooter,
PrimaryButton,
DefaultButton } from "@fluentui/react";

DefaultButton,
Panel,
PanelType} from "@fluentui/react";
import { Resizable, ResizableBox } from "react-resizable";
import { retryFile } from "../../api";
import styles from "./DocumentsDetailList.module.css";
import { deleteItem, DeleteItemRequest, resubmitItem, ResubmitItemRequest } from "../../api";
import { StatusContent } from "../StatusContent/StatusContent";
import Draggable from "react-draggable";
// import Resizable from "re-resizable";
// import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";

export interface IDocument {
key: string;
Expand Down Expand Up @@ -47,7 +53,6 @@ interface Props {
}

export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => {

const itemsRef = useRef(items);

const onColumnClick = (ev: React.MouseEvent<HTMLElement>, column: IColumn): void => {
Expand Down Expand Up @@ -215,17 +220,30 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => {

// ********************************************************************
// State detail dialog
const [value, setValue] = useState('Initial value');
const [stateDialogVisible, setStateDialogVisible] = useState(false);
const [stateDialogContent, setStateDialogContent] = useState<React.ReactNode>(null);
const scrollableContentRef = useRef<HTMLDivElement>(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 refreshProp = (item: any) => {
setValue(item);
};

const onStateColumnClick = (item: IDocument) => {
try {
const statusElements = item.status_updates.map((update, index) => (
<div key={index}>
<b>{update.status_timestamp}</b> - {update.status}
</div>
));
setStateDialogContent(statusElements);
refreshProp(item);
setStateDialogVisible(true);
} catch (error) {
console.error("Error on state column click:", error);
Expand Down Expand Up @@ -293,7 +311,7 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => {
data: 'string',
onRender: (item: IDocument) => (
<TooltipHost content={`${item.state} `}>
<span onClick={() => onStateColumnClick(item)} style={{ cursor: 'pointer' }}>
<span onClick={() => onStateColumnClick(item)} style={{ cursor: 'pointer', color:'blue', textDecoration:'underline' }}>
{item.state}
</span>
{item.state === 'Error' && <a href="javascript:void(0);" onClick={() => retryErroredFile(item)}> - Retry File</a>}
Expand Down Expand Up @@ -448,7 +466,23 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => {
<div>
<Notification message={notification.message} />
</div>
<Dialog

<Panel
headerText="Status Log"
isOpen={stateDialogVisible}
isBlocking={false}
onDismiss={() => setStateDialogVisible(false)}
closeButtonAriaLabel="Close"
onRenderFooterContent={() => <DefaultButton onClick={() => setStateDialogVisible(false)}>Close</DefaultButton>}
isFooterAtBottom={true}
type={PanelType.medium}
>
<div className={styles.resultspanel}>
<StatusContent item={value} />
</div>
</Panel>

{/* <Dialog
hidden={!stateDialogVisible}
onDismiss={() => setStateDialogVisible(false)}
dialogContentProps={{
Expand All @@ -466,7 +500,7 @@ export const DocumentsDetailList = ({ items, onFilesSorted}: Props) => {
<DialogFooter>
<PrimaryButton onClick={() => setStateDialogVisible(false)} text="OK" />
</DialogFooter>
</Dialog>
</Dialog> */}
</div>
);
}
49 changes: 49 additions & 0 deletions app/frontend/src/components/StatusContent/StatusContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import React, { useEffect, useMemo, useState } from "react";
import { Text } from "@fluentui/react";
import { Label } from '@fluentui/react/lib/Label';
import { Separator } from '@fluentui/react/lib/Separator';
import { getInfoData, GetInfoResponse } from "../../api";

interface Props {
className?: string;
item?: any;
}
interface Stat {
status_timestamp: string;
status: string; // replace 'string' with the actual type of 'timestamp'
// include other properties of 'stat' here
}
export const StatusContent = ({ item }: Props) => {
const data = item.status_updates.reverse();
// .sort((a: any, b: any) => new Date(b.status_timestamp).getTime() - new Date(a.status_timestamp).getTime());
const DisplayData=data.map(
(stat: Stat)=>{
return(
<tr>
<td>{stat.status}</td>
<td>{stat.status_timestamp.toString()}</td>
</tr>
)
}
)

return (
<div>
<Label>File Name</Label><Text>{item?.name}</Text>
<table className="table table-striped">
<thead>
<tr>
<th>Status</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
{DisplayData}
</tbody>
</table>
</div>
);
};

0 comments on commit 09d73bb

Please sign in to comment.