Compare commits

..

1 Commits

Author SHA1 Message Date
Asier Isayas
12442fadfb Mongo Shell and MS Graph changes (no RBAC functionality) 2024-07-11 17:12:28 -04:00
5 changed files with 37 additions and 70 deletions

View File

@@ -1,7 +1,8 @@
export interface QueryRequestOptions { export interface QueryRequestOptions {
$skipToken?: string; $skipToken?: string;
$top?: number; $top?: number;
subscriptions: string[]; $allowPartialScopes: boolean;
subscriptions?: string[];
} }
export interface QueryResponse { export interface QueryResponse {

View File

@@ -20,7 +20,7 @@
outline-offset: 2px; outline-offset: 2px;
} }
.outlineNone { .outlineNone{
outline: none !important; outline: none !important;
} }
@@ -28,8 +28,3 @@
.deleteQuery:focus::after { .deleteQuery:focus::after {
outline: none !important; outline: none !important;
} }
.highlightedButtonStyles {
outline: 1px dashed back;
background-color: #ebebeb;
}

View File

@@ -34,13 +34,12 @@ import { SamplePrompts, SamplePromptsProps } from "Explorer/QueryCopilot/Shared/
import { Action } from "Shared/Telemetry/TelemetryConstants"; import { Action } from "Shared/Telemetry/TelemetryConstants";
import { userContext } from "UserContext"; import { userContext } from "UserContext";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useQueryCopilot } from "hooks/useQueryCopilot";
import React, { useCallback, useRef, useState } from "react"; import React, { useRef, useState } from "react";
import HintIcon from "../../../images/Hint.svg"; import HintIcon from "../../../images/Hint.svg";
import RecentIcon from "../../../images/Recent.svg"; import RecentIcon from "../../../images/Recent.svg";
import errorIcon from "../../../images/close-black.svg"; import errorIcon from "../../../images/close-black.svg";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { useTabs } from "../../hooks/useTabs"; import { useTabs } from "../../hooks/useTabs";
import "../Controls/ThroughputInput/ThroughputInput.less";
import { useCopilotStore } from "../QueryCopilot/QueryCopilotContext"; import { useCopilotStore } from "../QueryCopilot/QueryCopilotContext";
import { useSelectedNode } from "../useSelectedNode"; import { useSelectedNode } from "../useSelectedNode";
@@ -109,7 +108,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setErrorMessage, setErrorMessage,
errorMessage, errorMessage,
} = useCopilotStore(); } = useCopilotStore();
const [focusedIndex, setFocusedIndex] = useState(-1);
const sampleProps: SamplePromptsProps = { const sampleProps: SamplePromptsProps = {
isSamplePromptsOpen: isSamplePromptsOpen, isSamplePromptsOpen: isSamplePromptsOpen,
setIsSamplePromptsOpen: setIsSamplePromptsOpen, setIsSamplePromptsOpen: setIsSamplePromptsOpen,
@@ -302,41 +301,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
return "Content is updated"; return "Content is updated";
} }
}; };
const openSamplePrompts = () => {
inputEdited.current = true;
setShowSamplePrompts(true);
};
const suggestionHistory = filteredHistories.concat(filteredSuggestedPrompts.map((item) => item.text));
const handleKeyDown: React.KeyboardEventHandler = (e) => {
const { key } = e;
if (key === "ArrowDown") {
setFocusedIndex((focusedIndex + 1) % suggestionHistory.length);
}
if (key === "ArrowUp") {
setFocusedIndex((focusedIndex + suggestionHistory.length - 1) % suggestionHistory.length);
}
if (key === "Enter") {
e.preventDefault();
handleSelection(focusedIndex);
}
};
const handleSelection = (selectedIndex: number) => {
const selectedItem = suggestionHistory[selectedIndex];
if (!selectedItem) {
return resetSearchComplete();
} else {
handlePromptSet(selectedItem);
}
};
const resetSearchComplete = useCallback(() => {
setFocusedIndex(-1);
setShowSamplePrompts(false);
}, []);
const handlePromptSet = (promptText: string) => {
inputEdited.current = true;
setUserPrompt(promptText);
};
React.useEffect(() => { React.useEffect(() => {
useTabs.getState().setIsQueryErrorThrown(false); useTabs.getState().setIsQueryErrorThrown(false);
@@ -367,13 +331,23 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
id="naturalLanguageInput" id="naturalLanguageInput"
value={userPrompt} value={userPrompt}
onChange={handleUserPromptChange} onChange={handleUserPromptChange}
onClick={openSamplePrompts} onClick={() => {
onFocus={() => setShowSamplePrompts(true)} inputEdited.current = true;
onKeyDown={handleKeyDown} setShowSamplePrompts(true);
}}
onKeyDown={(e) => {
if (e.key === "Enter" && userPrompt) {
inputEdited.current = true;
startGenerateQueryProcess();
}
}}
style={{ lineHeight: 30 }} style={{ lineHeight: 30 }}
styles={{ styles={{
root: { width: "100%" }, root: { width: "100%" },
suffix: { background: "none", padding: 0 }, suffix: {
background: "none",
padding: 0,
},
fieldGroup: { fieldGroup: {
borderRadius: 4, borderRadius: 4,
borderColor: "#D1D1D1", borderColor: "#D1D1D1",
@@ -386,8 +360,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}, },
}} }}
disabled={isGeneratingQuery} disabled={isGeneratingQuery}
autoComplete="list" autoComplete="off"
aria-expanded={showSamplePrompts}
placeholder="Ask a question in natural language and well generate the query for you." placeholder="Ask a question in natural language and well generate the query for you."
aria-labelledby="copilot-textfield-label" aria-labelledby="copilot-textfield-label"
onRenderSuffix={() => { onRenderSuffix={() => {
@@ -396,10 +369,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
iconProps={{ iconName: "Send" }} iconProps={{ iconName: "Send" }}
disabled={isGeneratingQuery || !userPrompt.trim()} disabled={isGeneratingQuery || !userPrompt.trim()}
style={{ background: "none" }} style={{ background: "none" }}
onClick={() => { onClick={() => startGenerateQueryProcess()}
startGenerateQueryProcess();
setShowSamplePrompts(false);
}}
aria-label="Send" aria-label="Send"
/> />
); );
@@ -464,7 +434,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}} }}
onRenderIcon={() => <Image src={RecentIcon} styles={{ root: { overflow: "unset" } }} />} onRenderIcon={() => <Image src={RecentIcon} styles={{ root: { overflow: "unset" } }} />}
styles={promptStyles} styles={promptStyles}
className={focusedIndex === i ? "highlightedButtonStyles" : "buttonstyles"}
> >
{history} {history}
</DefaultButton> </DefaultButton>
@@ -485,7 +454,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
> >
Suggested Prompts Suggested Prompts
</Text> </Text>
{filteredSuggestedPrompts.map((prompt, index) => ( {filteredSuggestedPrompts.map((prompt) => (
<DefaultButton <DefaultButton
key={prompt.id} key={prompt.id}
onClick={() => { onClick={() => {
@@ -495,7 +464,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}} }}
onRenderIcon={() => <Image src={HintIcon} />} onRenderIcon={() => <Image src={HintIcon} />}
styles={promptStyles} styles={promptStyles}
className={focusedIndex === filteredHistories.length + index ? "highlightedButtonStyles" : ""}
> >
{prompt.text} {prompt.text}
</DefaultButton> </DefaultButton>

View File

@@ -1,5 +1,6 @@
import { useMongoProxyEndpoint } from "Common/MongoProxyClient"; import { useMongoProxyEndpoint } from "Common/MongoProxyClient";
import React, { Component } from "react"; import React, { Component } from "react";
import * as Constants from "../../../Common/Constants";
import { configContext } from "../../../ConfigContext"; import { configContext } from "../../../ConfigContext";
import * as ViewModels from "../../../Contracts/ViewModels"; import * as ViewModels from "../../../Contracts/ViewModels";
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants"; import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
@@ -112,6 +113,12 @@ export default class MongoShellTabComponent extends Component<
const resourceId = databaseAccount?.id; const resourceId = databaseAccount?.id;
const accountName = databaseAccount?.name; const accountName = databaseAccount?.name;
const documentEndpoint = databaseAccount?.properties.mongoEndpoint || databaseAccount?.properties.documentEndpoint; const documentEndpoint = databaseAccount?.properties.mongoEndpoint || databaseAccount?.properties.documentEndpoint;
const mongoEndpoint =
documentEndpoint.substr(
Constants.MongoDBAccounts.protocol.length + 3,
documentEndpoint.length -
(Constants.MongoDBAccounts.protocol.length + 2 + Constants.MongoDBAccounts.defaultPort.length),
) + Constants.MongoDBAccounts.defaultPort.toString();
const databaseId = this.props.collection.databaseId; const databaseId = this.props.collection.databaseId;
const collectionId = this.props.collection.id(); const collectionId = this.props.collection.id();
const apiEndpoint = this._useMongoProxyEndpoint const apiEndpoint = this._useMongoProxyEndpoint
@@ -125,7 +132,7 @@ export default class MongoShellTabComponent extends Component<
data: { data: {
resourceId: resourceId, resourceId: resourceId,
accountName: accountName, accountName: accountName,
mongoEndpoint: documentEndpoint, mongoEndpoint: this._useMongoProxyEndpoint ? documentEndpoint : mongoEndpoint,
authorization: authorization, authorization: authorization,
databaseId: databaseId, databaseId: databaseId,
collectionId: collectionId, collectionId: collectionId,

View File

@@ -51,17 +51,13 @@ export async function fetchSubscriptionsFromGraph(accessToken: string): Promise<
do { do {
const body = { const body = {
query: subscriptionsQuery, query: subscriptionsQuery,
...(skipToken
? {
options: {
$skipToken: skipToken,
} as QueryRequestOptions,
}
: {
options: { options: {
$allowPartialScopes: true,
$top: 150, $top: 150,
} as QueryRequestOptions, ...(skipToken && {
$skipToken: skipToken,
}), }),
} as QueryRequestOptions,
}; };
const response = await fetch(managementResourceGraphAPIURL, { const response = await fetch(managementResourceGraphAPIURL, {