/* eslint-disable no-console */ import { FeedOptions } from "@azure/cosmos"; import { IconButton, Image, Link, Stack, Text, TextField } from "@fluentui/react"; import { QueryCopilotSampleContainerId, QueryCopilotSampleDatabaseId } from "Common/Constants"; import { getErrorMessage, handleError } from "Common/ErrorHandlingUtils"; import { shouldEnableCrossPartitionKey } from "Common/HeadersUtility"; import { MinimalQueryIterator } from "Common/IteratorUtilities"; import { queryDocuments } from "Common/dataAccess/queryDocuments"; import { queryDocumentsPage } from "Common/dataAccess/queryDocumentsPage"; import { QueryResults } from "Contracts/ViewModels"; import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent"; import { EditorReact } from "Explorer/Controls/Editor/EditorReact"; import Explorer from "Explorer/Explorer"; import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter"; import { SaveQueryPane } from "Explorer/Panes/SaveQueryPane/SaveQueryPane"; import { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection"; import { queryPagesUntilContentPresent } from "Utils/QueryUtils"; import { useSidePanel } from "hooks/useSidePanel"; import React, { useState } from "react"; import SplitterLayout from "react-splitter-layout"; import CopilotIcon from "../../../images/Copilot.svg"; import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg"; import SaveQueryIcon from "../../../images/save-cosmos.svg"; interface QueryCopilotTabProps { initialInput: string; explorer: Explorer; } export const QueryCopilotTab: React.FC = ({ initialInput, explorer, }: QueryCopilotTabProps): JSX.Element => { const [userInput, setUserInput] = useState(initialInput || ""); const [query, setQuery] = useState(""); const [selectedQuery, setSelectedQuery] = useState(""); const [isExecuting, setIsExecuting] = useState(false); const [queryIterator, setQueryIterator] = useState(); const [queryResults, setQueryResults] = useState(); const [errorMessage, setErrorMessage] = useState(""); const generateQuery = (): string => { switch (userInput) { case "Write a query to return all records in this table": return "SELECT * FROM c"; case "Write a query to return all records in this table created in the last thirty days": return "SELECT * FROM c WHERE c._ts > (DATEDIFF(s, '1970-01-01T00:00:00Z', GETUTCDATE()) - 2592000) * 1000"; case `Write a query to return all records in this table created in the last thirty days which also have the record owner as "Contoso"`: return `SELECT * FROM c WHERE c.owner = "Contoso" AND c._ts > (DATEDIFF(s, '1970-01-01T00:00:00Z', GETUTCDATE()) - 2592000) * 1000`; default: return ""; } }; const onExecuteQueryClick = async (): Promise => { const queryToExecute = selectedQuery || query; const queryIterator = queryDocuments(QueryCopilotSampleDatabaseId, QueryCopilotSampleContainerId, queryToExecute, { enableCrossPartitionQuery: shouldEnableCrossPartitionKey(), } as FeedOptions); setQueryIterator(queryIterator); setTimeout(async () => { await queryDocumentsPerPage(0, queryIterator); }, 100); }; const queryDocumentsPerPage = async (firstItemIndex: number, queryIterator: MinimalQueryIterator): Promise => { try { setIsExecuting(true); const queryResults: QueryResults = await queryPagesUntilContentPresent( firstItemIndex, async (firstItemIndex: number) => queryDocumentsPage(QueryCopilotSampleContainerId, queryIterator, firstItemIndex) ); setQueryResults(queryResults); setErrorMessage(""); } catch (error) { const errorMessage = getErrorMessage(error); setErrorMessage(errorMessage); handleError(errorMessage, "executeQueryCopilotTab"); } finally { setIsExecuting(false); } }; const getCommandbarButtons = (): CommandButtonComponentProps[] => { const executeQueryBtnLabel = selectedQuery ? "Execute Selection" : "Execute Query"; const executeQueryBtn = { iconSrc: ExecuteQueryIcon, iconAlt: executeQueryBtnLabel, onCommandClick: () => onExecuteQueryClick(), commandButtonLabel: executeQueryBtnLabel, ariaLabel: executeQueryBtnLabel, hasPopup: false, }; const saveQueryBtn = { iconSrc: SaveQueryIcon, iconAlt: "Save Query", onCommandClick: () => useSidePanel.getState().openSidePanel("Save Query", ), commandButtonLabel: "Save Query", ariaLabel: "Save Query", hasPopup: false, }; return [executeQueryBtn, saveQueryBtn]; }; React.useEffect(() => { useCommandBar.getState().setContextButtons(getCommandbarButtons()); }, [query]); return ( Copilot setUserInput(newValue)} style={{ lineHeight: 30 }} styles={{ root: { width: "90%" } }} /> setQuery(generateQuery())} /> AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.{" "} Read preview terms setQuery(newQuery)} onContentSelected={(selectedQuery: string) => setSelectedQuery(selectedQuery)} /> queryDocumentsPerPage(firstItemIndex, queryIterator)} /> ); };