/** * React component for control bar */ import { Dropdown, IDropdownOption } from "@fluentui/react"; import * as React from "react"; import AnimateHeight from "react-animate-height"; import LoaderIcon from "../../../../images/circular_loader_black_16x16.gif"; import ClearIcon from "../../../../images/Clear.svg"; import ErrorBlackIcon from "../../../../images/error_black.svg"; import ErrorRedIcon from "../../../../images/error_red.svg"; import infoBubbleIcon from "../../../../images/info-bubble-9x9.svg"; import InfoIcon from "../../../../images/info_color.svg"; import LoadingIcon from "../../../../images/loading.svg"; import ChevronDownIcon from "../../../../images/QueryBuilder/CollapseChevronDown_16x.png"; import ChevronUpIcon from "../../../../images/QueryBuilder/CollapseChevronUp_16x.png"; import { ClientDefaults, KeyCodes } from "../../../Common/Constants"; import { userContext } from "../../../UserContext"; /** * Log levels */ export enum ConsoleDataType { Info = 0, Error = 1, InProgress = 2, } /** * Interface for the data/content that will be recorded */ export interface ConsoleData { type: ConsoleDataType; date: string; message: string; id?: string; } export interface NotificationConsoleComponentProps { isConsoleExpanded: boolean; consoleData: ConsoleData; inProgressConsoleDataIdToBeDeleted: string; setIsConsoleExpanded: (isExpanded: boolean) => void; } interface NotificationConsoleComponentState { headerStatus: string; selectedFilter: string; allConsoleData: ConsoleData[]; } export class NotificationConsoleComponent extends React.Component< NotificationConsoleComponentProps, NotificationConsoleComponentState > { private static readonly transitionDurationMs = 200; private static readonly FilterOptions = [ { key: "All", text: "All" }, { key: "In Progress", text: "In progress" }, { key: "Info", text: "Info" }, { key: "Error", text: "Error" }, ]; private headerTimeoutId?: number; private prevHeaderStatus: string; private consoleHeaderElement?: HTMLElement; constructor(props: NotificationConsoleComponentProps) { super(props); this.state = { headerStatus: undefined, selectedFilter: NotificationConsoleComponent.FilterOptions[0].key, allConsoleData: props.consoleData ? [props.consoleData] : [], }; this.prevHeaderStatus = undefined; } public componentDidUpdate( prevProps: NotificationConsoleComponentProps, prevState: NotificationConsoleComponentState ): void { const currentHeaderStatus = NotificationConsoleComponent.extractHeaderStatus(this.props.consoleData); if ( this.prevHeaderStatus !== currentHeaderStatus && currentHeaderStatus !== undefined && prevState.headerStatus !== currentHeaderStatus ) { this.setHeaderStatus(currentHeaderStatus); } // Call setHeaderStatus() only to clear HeaderStatus or update status to a different value. // Cache previous headerStatus externally. Otherwise, simply comparing with previous state/props will cause circular // updates: currentHeaderStatus -> "" -> currentHeaderStatus -> "" etc. this.prevHeaderStatus = currentHeaderStatus; if (this.props.consoleData || this.props.inProgressConsoleDataIdToBeDeleted) { this.updateConsoleData(prevProps); } } public setElememntRef = (element: HTMLElement): void => { this.consoleHeaderElement = element; }; public render(): JSX.Element { const numInProgress = this.state.allConsoleData.filter( (data: ConsoleData) => data.type === ConsoleDataType.InProgress ).length; const numErroredItems = this.state.allConsoleData.filter((data: ConsoleData) => data.type === ConsoleDataType.Error) .length; const numInfoItems = this.state.allConsoleData.filter((data: ConsoleData) => data.type === ConsoleDataType.Info) .length; return (