Compare commits

..

14 Commits

Author SHA1 Message Date
Sung-Hyun Kang (from Dev Box)
497d82a88c Merge remote-tracking branch 'origin/master' into copilot_publicpreview 2023-11-10 18:43:55 -06:00
Sung-Hyun Kang (from Dev Box)
da09ba671c Updated the endpoint 2023-11-10 18:41:40 -06:00
Sung-Hyun Kang (from Dev Box)
6e1b104b72 don't call ARM when connectionstring login 2023-11-10 15:55:28 -06:00
Sung-Hyun Kang (from Dev Box)
5433d61bd8 fix formatting 2023-11-10 15:31:53 -06:00
Sung-Hyun Kang (from Dev Box)
feba77e2bf fix formatting 2023-11-10 15:27:33 -06:00
Sung-Hyun Kang (from Dev Box)
22ce69d20c fix formatting 2023-11-10 15:23:54 -06:00
Sung-Hyun Kang (from Dev Box)
d862b929ec fix formatting 2023-11-10 15:18:51 -06:00
Sung-Hyun Kang (from Dev Box)
e626f5218d increase test timeout 2023-11-10 15:15:28 -06:00
Sung-Hyun Kang (from Dev Box)
58aff4f07b add timeout for ARM calls 2023-11-10 15:04:27 -06:00
Sung-Hyun Kang (from Dev Box)
e406bf8190 Update branding and AFEC 2023-11-10 12:44:47 -06:00
Sung-Hyun Kang (from Dev Box)
45bd16e17f Update branding and AFEC 2023-11-10 11:47:11 -06:00
Sung-Hyun Kang (from Dev Box)
7d557df4e0 P1 bugs for copilot 2023-11-09 20:43:43 -06:00
Sung-Hyun Kang (from Dev Box)
b4d6ad172b P1 bugs for copilot 2023-11-09 20:38:14 -06:00
Sung-Hyun Kang (from Dev Box)
a12e8b050f P1 bugs for copilot 2023-11-09 20:36:26 -06:00
10 changed files with 37 additions and 45 deletions

View File

@@ -148,6 +148,9 @@ export function client(): Cosmos.CosmosClient {
endpoint: endpoint() || "https://cosmos.azure.com", // CosmosClient gets upset if we pass a bad URL. This should never actually get called
key: userContext.masterKey,
tokenProvider,
connectionPolicy: {
enableEndpointDiscovery: false,
},
userAgentSuffix: "Azure Portal",
defaultHeaders: _defaultHeaders,
};

View File

@@ -275,7 +275,6 @@ export default class Explorer {
const NINETY_DAYS_IN_MS = 7776000000;
const ONE_DAY_IN_MS = 86400000;
const THREE_DAYS_IN_MS = 259200000;
const isAccountNewerThanNinetyDays = isAccountNewerThanThresholdInMs(
userContext.databaseAccount?.systemData?.createdAt || "",
NINETY_DAYS_IN_MS,
@@ -295,32 +294,32 @@ export default class Explorer {
}
}
// Try Cosmos DB subscription - survey shown to 100% of users at day 1 in Data Explorer.
// Try Cosmos DB subscription - survey shown to random 25% of users at day 1 in Data Explorer.
if (userContext.isTryCosmosDBSubscription) {
if (isAccountNewerThanThresholdInMs(userContext.databaseAccount?.systemData?.createdAt || "", ONE_DAY_IN_MS)) {
this.sendNPSMessage();
if (
isAccountNewerThanThresholdInMs(userContext.databaseAccount?.systemData?.createdAt || "", ONE_DAY_IN_MS) &&
this.getRandomInt(100) < 25
) {
sendMessage({ type: MessageTypes.DisplayNPSSurvey });
localStorage.setItem("lastSubmitted", Date.now().toString());
}
} else {
// An existing account is older than 3 days but less than 90 days old. For existing account show to 100% of users in Data Explorer.
if (
!isAccountNewerThanThresholdInMs(userContext.databaseAccount?.systemData?.createdAt || "", THREE_DAYS_IN_MS) &&
isAccountNewerThanNinetyDays
) {
this.sendNPSMessage();
// An existing account is lesser than 90 days old. For existing account show to random 10 % of users in Data Explorer.
if (isAccountNewerThanNinetyDays) {
if (this.getRandomInt(100) < 10) {
sendMessage({ type: MessageTypes.DisplayNPSSurvey });
localStorage.setItem("lastSubmitted", Date.now().toString());
}
} else {
// An existing account is greater than 90 days. For existing account show to random 33% of users in Data Explorer.
if (this.getRandomInt(100) < 33) {
this.sendNPSMessage();
// An existing account is greater than 90 days. For existing account show to random 25 % of users in Data Explorer.
if (this.getRandomInt(100) < 25) {
sendMessage({ type: MessageTypes.DisplayNPSSurvey });
localStorage.setItem("lastSubmitted", Date.now().toString());
}
}
}
}
private sendNPSMessage() {
sendMessage({ type: MessageTypes.DisplayNPSSurvey });
localStorage.setItem("lastSubmitted", Date.now().toString());
}
public async refreshDatabaseForResourceToken(): Promise<void> {
const databaseId = userContext.parsedResourceToken?.databaseId;
const collectionId = userContext.parsedResourceToken?.collectionId;
@@ -1397,7 +1396,6 @@ export default class Explorer {
]);
useQueryCopilot.getState().setCopilotEnabled(copilotEnabled);
useQueryCopilot.getState().setCopilotUserDBEnabled(copilotUserDBEnabled);
useQueryCopilot.getState().setShowWelcomeModal(window.localStorage.getItem("hideWelcomeModal") !== "true");
}
public async refreshSampleData(): Promise<void> {

View File

@@ -1431,6 +1431,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
this.setState({ isExecuting: false });
TelemetryProcessor.traceSuccess(Action.CreateCollection, telemetryData, startKey);
useSidePanel.getState().closeSidePanel();
// open NPS Survey Dialog once the collection is created
this.props.explorer.openNPSSurveyDialog();
} catch (error) {
const errorMessage: string = getErrorMessage(error);
this.setState({ isExecuting: false, errorMessage, showErrorDetails: true });

View File

@@ -336,8 +336,7 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
directionalHint={4}
>
<Icon
ariaLabel="Enable analytical store capability to perform near real-time analytics on your operational data, without
impacting the performance of transactional workloads."
ariaLabel="Enable analytical store capability to perform near real-time analytics on your operational data, without impacting the performance of transactional workloads."
className="panelInfoIcon"
iconName="Info"
tabIndex={0}

View File

@@ -1,6 +1,5 @@
import { IconButton, Image, Link, Modal, PrimaryButton, Stack, StackItem, Text } from "@fluentui/react";
import { useBoolean } from "@fluentui/react-hooks";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react";
import Flash from "../../../../images/CopilotFlash.svg";
import Thumb from "../../../../images/CopilotThumb.svg";
@@ -14,11 +13,7 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
if (visible) {
window.localStorage.setItem("hideWelcomeModal", "true");
}
}, []);
React.useEffect(() => {
useQueryCopilot.getState().setShowWelcomeModal(isModalVisible);
}, [isModalVisible]);
});
return (
<>

View File

@@ -35,7 +35,7 @@ import { GenerateSQLQueryResponse, QueryCopilotProps } from "Explorer/QueryCopil
import { SamplePrompts, SamplePromptsProps } from "Explorer/QueryCopilot/Shared/SamplePrompts/SamplePrompts";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { userContext } from "UserContext";
import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React, { useRef, useState } from "react";
import HintIcon from "../../../images/Hint.svg";
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
@@ -72,6 +72,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
containerId,
}: QueryCopilotPromptProps): JSX.Element => {
const [copilotTeachingBubbleVisible, { toggle: toggleCopilotTeachingBubbleVisible }] = useBoolean(false);
const inputEdited = useRef(false);
const {
openFeedbackModal,
hideFeedbackModalForLikedQueries,
@@ -109,8 +110,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
errorMessage,
} = useCopilotStore();
const inputEdited = useRef(!!userPrompt);
const sampleProps: SamplePromptsProps = {
isSamplePromptsOpen: isSamplePromptsOpen,
setIsSamplePromptsOpen: setIsSamplePromptsOpen,
@@ -275,7 +274,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
const showTeachingBubble = (): void => {
if (!inputEdited.current) {
setTimeout(() => {
if (!useQueryCopilot.getState().showWelcomeModal && !userPrompt && !inputEdited.current) {
if (!inputEdited.current && !isWelcomModalVisible()) {
toggleCopilotTeachingBubbleVisible();
inputEdited.current = true;
}
@@ -283,6 +282,10 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}
};
const isWelcomModalVisible = (): boolean => {
return localStorage.getItem("hideWelcomeModal") !== "true";
};
const clearFeedback = () => {
resetButtonState();
resetQueryResults();
@@ -302,7 +305,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
React.useEffect(() => {
showTeachingBubble();
useQueryCopilot.subscribe(showTeachingBubble, (state: QueryCopilotState) => state.showWelcomeModal);
useTabs.getState().setIsQueryErrorThrown(false);
}, []);
@@ -589,7 +591,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
</CommandBarButton>
</Stack>
)}
<WelcomeModal visible={useQueryCopilot.getState().showWelcomeModal} />
<WelcomeModal visible={isWelcomModalVisible()} />
{isSamplePromptsOpen && <SamplePrompts sampleProps={sampleProps} />}
{query !== "" && query.trim().length !== 0 && (
<DeletePopup

View File

@@ -93,7 +93,7 @@ export const getCopilotEnabled = async (): Promise<boolean> => {
}
if (!response?.ok) {
return false;
throw new Error(await response?.text());
}
const copilotPortalConfiguration = (await response?.json()) as CopilotEnabledConfiguration;

View File

@@ -104,13 +104,12 @@ interface IQueryTabStates {
export const QueryTabFunctionComponent = (props: IQueryTabComponentProps): any => {
const copilotStore = useCopilotStore();
const copilotGlobalStore = useQueryCopilot();
const isSampleCopilotActive = useSelectedNode.getState().isQueryCopilotCollectionSelected();
const queryTabProps = {
...props,
copilotEnabled:
copilotGlobalStore.copilotEnabled &&
(copilotGlobalStore.copilotUserDBEnabled || (isSampleCopilotActive && !!userContext.sampleDataConnectionInfo)),
useQueryCopilot().copilotEnabled &&
(useQueryCopilot().copilotUserDBEnabled || (isSampleCopilotActive && !!userContext.sampleDataConnectionInfo)),
isSampleCopilotActive: isSampleCopilotActive,
copilotStore: copilotStore,
};

View File

@@ -420,11 +420,9 @@ async function configurePortal(): Promise<Explorer> {
updateContextsFromPortalMessage(inputs);
explorer = new Explorer();
resolve(explorer);
if (userContext.apiType === "Postgres" || userContext.apiType === "SQL" || userContext.apiType === "Mongo") {
setTimeout(() => explorer.openNPSSurveyDialog(), 3000);
if (userContext.apiType === "Postgres") {
explorer.openNPSSurveyDialog();
}
if (openAction) {
handleOpenAction(openAction, useDatabases.getState().databases, explorer);
}

View File

@@ -36,7 +36,6 @@ export interface QueryCopilotState {
generatedQueryComments: string;
wasCopilotUsed: boolean;
showWelcomeSidebar: boolean;
showWelcomeModal: boolean;
showCopilotSidebar: boolean;
chatMessages: CopilotMessage[];
shouldIncludeInMessages: boolean;
@@ -78,7 +77,6 @@ export interface QueryCopilotState {
setGeneratedQueryComments: (generatedQueryComments: string) => void;
setWasCopilotUsed: (wasCopilotUsed: boolean) => void;
setShowWelcomeSidebar: (showWelcomeSidebar: boolean) => void;
setShowWelcomeModal: (showWelcomeModal: boolean) => void;
setShowCopilotSidebar: (showCopilotSidebar: boolean) => void;
setChatMessages: (chatMessages: CopilotMessage[]) => void;
setShouldIncludeInMessages: (shouldIncludeInMessages: boolean) => void;
@@ -124,7 +122,6 @@ export const useQueryCopilot: QueryCopilotStore = create((set) => ({
generatedQueryComments: "",
wasCopilotUsed: false,
showWelcomeSidebar: true,
showWelcomeModal: true,
showCopilotSidebar: false,
chatMessages: [],
shouldIncludeInMessages: true,
@@ -177,7 +174,6 @@ export const useQueryCopilot: QueryCopilotStore = create((set) => ({
setGeneratedQueryComments: (generatedQueryComments: string) => set({ generatedQueryComments }),
setWasCopilotUsed: (wasCopilotUsed: boolean) => set({ wasCopilotUsed }),
setShowWelcomeSidebar: (showWelcomeSidebar: boolean) => set({ showWelcomeSidebar }),
setShowWelcomeModal: (showWelcomeModal: boolean) => set({ showWelcomeModal }),
setShowCopilotSidebar: (showCopilotSidebar: boolean) => set({ showCopilotSidebar }),
setChatMessages: (chatMessages: CopilotMessage[]) => set({ chatMessages }),
setShouldIncludeInMessages: (shouldIncludeInMessages: boolean) => set({ shouldIncludeInMessages }),