Move Alert Provider to top level of index.js

This commit is contained in:
Ian Arawjo 2024-03-30 21:54:20 -04:00
parent cf64cbc54b
commit 43de1dd98c
5 changed files with 63 additions and 17 deletions

View File

@ -37,7 +37,7 @@ import CodeEvaluatorNode from "./CodeEvaluatorNode";
import VisNode from "./VisNode";
import InspectNode from "./InspectorNode";
import ScriptNode from "./ScriptNode";
import { AlertModalProvider, AlertModalContext } from "./AlertModal";
import { AlertModalContext } from "./AlertModal";
import ItemsNode from "./ItemsNode";
import TabularDataNode from "./TabularDataNode";
import JoinNode from "./JoinNode";
@ -898,7 +898,7 @@ const App = () => {
);
} else
return (
<AlertModalProvider>
<div>
<GlobalSettingsModal ref={settingsModal} />
<LoadingOverlay visible={isLoading} overlayBlur={1} />
<ExampleFlowsModal
@ -946,6 +946,10 @@ const App = () => {
snapToGrid={true}
snapGrid={snapGrid}
onInit={onInit}
onError={(err) => {
// Suppress ReactFlow warnings spamming the console.
// console.log(err);
}}
>
<Background color="#999" gap={16} />
<Controls showZoom={true} />
@ -1223,7 +1227,7 @@ const App = () => {
Send us feedback
</a>
</div>
</AlertModalProvider>
</div>
);
};

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useContext } from "react";
import { Handle, Position } from "reactflow";
import useStore from "./store";
import BaseNode from "./BaseNode";
@ -6,6 +6,7 @@ import NodeLabel from "./NodeLabelComponent";
import LLMResponseInspector, { exportToExcel } from "./LLMResponseInspector";
import { grabResponses } from "./backend/backend";
import { LLMResponse } from "./backend/typing";
import { AlertModalContext } from "./AlertModal";
export interface InspectorNodeProps {
data: {
@ -26,6 +27,7 @@ const InspectorNode: React.FC<InspectorNodeProps> = ({ data, id }) => {
const [pastInputs, setPastInputs] = useState<string>("");
const inputEdgesForNode = useStore((state) => state.inputEdgesForNode);
const setDataPropsForNode = useStore((state) => state.setDataPropsForNode);
const showAlert = useContext(AlertModalContext);
const handleOnConnect = () => {
// For some reason, 'on connect' is called twice upon connection.
@ -74,7 +76,13 @@ const InspectorNode: React.FC<InspectorNodeProps> = ({ data, id }) => {
<button
className="custom-button"
key="export-data"
onClick={() => exportToExcel(jsonResponses ?? [])}
onClick={() => {
try {
exportToExcel(jsonResponses ?? []);
} catch (e) {
showAlert && showAlert(e as Error);
}
}}
>
Export data
</button>,

View File

@ -38,7 +38,12 @@ import {
genResponseTextsDisplay,
} from "./ResponseBoxes";
import { getLabelForResponse } from "./ResponseRatingToolbar";
import { Dict, LLMResponse, LLMResponseData } from "./backend/typing";
import {
Dict,
LLMResponse,
LLMResponseData,
isImageResponseData,
} from "./backend/typing";
// Helper funcs
const getLLMName = (resp_obj: LLMResponse) =>
@ -55,8 +60,8 @@ function getIndicesOfSubstringMatches(
escapeRegExp(substr),
"g" + (caseSensitive ? "" : "i"),
);
let result;
const indices = [];
let result: RegExpExecArray | null;
const indices: number[] = [];
while ((result = regex.exec(s))) indices.push(result.index);
return indices;
}
@ -71,9 +76,9 @@ function splitAndIncludeDelimiter(
if (indices.length === 0) return [s];
const len_sub = substr.length;
const results = [];
const results: string[] = [];
let prev_idx = 0;
indices.forEach((idx) => {
indices.forEach((idx: number) => {
const pre_delim = s.substring(prev_idx, idx);
const delim = s.substring(idx, idx + len_sub);
results.push(pre_delim);
@ -119,10 +124,21 @@ export const exportToExcel = (
!jsonResponses ||
(Array.isArray(jsonResponses) && jsonResponses.length === 0)
) {
console.warn(
throw new Error(
"No responses to export. Try connecting the inspector node to a prompt node or evaluator node.",
);
return;
}
// Check format of responses
// TODO: Support export of images in Excel sheets
if (
jsonResponses.some(
(r) => r.responses.length > 0 && isImageResponseData(r.responses[0]),
)
) {
throw new Error(
"Images cannot be exported to Excel at this time. If you need this feature and you are a developer, please consider submitting a PR to our GitHub repository.",
);
}
// We can construct the data as an array of JSON dicts, with keys as header names:

View File

@ -2,11 +2,18 @@
* A fullscreen version of the Inspect node that
* appears in a Mantine modal pop-up which takes up much of the screen.
*/
import React, { forwardRef, useImperativeHandle, lazy, Suspense } from "react";
import React, {
forwardRef,
useImperativeHandle,
lazy,
Suspense,
useContext,
} from "react";
import { LoadingOverlay, Modal } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { exportToExcel } from "./LLMResponseInspector";
import { LLMResponse } from "./backend/typing";
import { AlertModalContext } from "./AlertModal";
// Lazy load the inspector view
const LLMResponseInspector = lazy(() => import("./LLMResponseInspector"));
@ -25,6 +32,7 @@ const LLMResponseInspectorModal = forwardRef<
>(function LLMResponseInspectorModal(props, ref) {
// const inspectorRef = useRef(null);
const [opened, { open, close }] = useDisclosure(false);
const showAlert = useContext(AlertModalContext);
// const [openedOnce, setOpenedOnce] = useState(false);
// This gives the parent access to triggering the modal
@ -50,7 +58,14 @@ const LLMResponseInspectorModal = forwardRef<
<button
className="custom-button"
style={{ marginTop: "auto", marginRight: "14px", float: "right" }}
onClick={() => exportToExcel(props.jsonResponses)}
onClick={() => {
try {
exportToExcel(props.jsonResponses);
} catch (e) {
close();
showAlert && showAlert(e as Error);
}
}}
>
Export data to Excel
</button>

View File

@ -4,13 +4,16 @@ import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { ContextMenuProvider } from "mantine-contextmenu";
import { AlertModalProvider } from "./AlertModal";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<ContextMenuProvider>
<App />
</ContextMenuProvider>
<AlertModalProvider>
<ContextMenuProvider>
<App />
</ContextMenuProvider>
</AlertModalProvider>
</React.StrictMode>,
);