Compare commits

..

4 Commits

Author SHA1 Message Date
hardiknai-techm
e5f65ee5b7 Merge branch 'master' of https://github.com/Azure/cosmos-explorer into does_not_pass_the_Copied 2021-10-12 20:32:37 +05:30
Hardikkumar Nai
bfd4948fb9 absulte_path setting (#984)
* absulte_path setting

* resolve build time error
2021-10-12 07:38:34 -07:00
hardiknai-techm
61964f095d resolve lint error 2021-10-04 18:23:47 +05:30
hardiknai-techm
43439f65a9 Open new screen: Screen reader does not pass the 'Copied' information after selecting 'Copy' button. 2021-10-01 20:34:47 +05:30
18 changed files with 116 additions and 117 deletions

View File

@@ -113,10 +113,13 @@ src/Explorer/Tree/ConflictId.ts
src/Explorer/Tree/DocumentId.ts
src/Explorer/Tree/ObjectId.ts
src/Explorer/Tree/ResourceTokenCollection.ts
src/Explorer/Tree/StoredProcedure.ts
src/Explorer/Tree/TreeComponents.ts
src/Explorer/WaitsForTemplateViewModel.ts
src/GitHub/GitHubClient.test.ts
src/GitHub/GitHubClient.ts
src/Index.ts
src/Platform/Hosted/Authorization.ts
src/ReactDevTools.ts
src/Shared/Constants.ts
src/Shared/DefaultExperienceUtility.test.ts

View File

@@ -22,5 +22,6 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": true
}
},
"typescript.preferences.importModuleSpecifier": "non-relative"
}

View File

@@ -129,6 +129,8 @@ module.exports = {
// The test environment that will be used for testing
// testEnvironment: "jest-environment-jsdom",
modulePaths: ["node_modules", "<rootDir>/src"],
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},

View File

@@ -4,6 +4,8 @@ import * as React from "react";
import { useFullScreenURLs } from "../hooks/useFullScreenURLs";
export const OpenFullScreen: React.FunctionComponent = () => {
const [isReadUrlCopy, setIsReadUrlCopy] = React.useState<boolean>(false);
const [isReadWriteUrlCopy, setIsReadWriteUrlCopy] = React.useState<boolean>(false);
const result = useFullScreenURLs();
if (!result) {
return <Spinner label="Generating URLs..." ariaLive="assertive" labelPosition="right" />;
@@ -25,8 +27,9 @@ export const OpenFullScreen: React.FunctionComponent = () => {
<DefaultButton
onClick={() => {
copyToClipboard(readWriteUrl);
setIsReadWriteUrlCopy(true);
}}
text="Copy"
text={isReadWriteUrlCopy ? "Copied" : "Copy"}
iconProps={{ iconName: "Copy" }}
/>
<PrimaryButton
@@ -41,9 +44,10 @@ export const OpenFullScreen: React.FunctionComponent = () => {
<Stack horizontal tokens={{ childrenGap: 10 }}>
<DefaultButton
onClick={() => {
setIsReadUrlCopy(true);
copyToClipboard(readUrl);
}}
text="Copy"
text={isReadUrlCopy ? "Copied" : "Copy"}
iconProps={{ iconName: "Copy" }}
/>
<PrimaryButton

View File

@@ -13,21 +13,21 @@ import {
Text,
TooltipHost,
} from "@fluentui/react";
import * as Constants from "Common/Constants";
import { createCollection } from "Common/dataAccess/createCollection";
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
import { configContext, Platform } from "ConfigContext";
import * as DataModels from "Contracts/DataModels";
import { SubscriptionType } from "Contracts/SubscriptionType";
import { useSidePanel } from "hooks/useSidePanel";
import React from "react";
import * as Constants from "../../Common/Constants";
import { createCollection } from "../../Common/dataAccess/createCollection";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
import { configContext, Platform } from "../../ConfigContext";
import * as DataModels from "../../Contracts/DataModels";
import { SubscriptionType } from "../../Contracts/SubscriptionType";
import { useSidePanel } from "../../hooks/useSidePanel";
import { CollectionCreation } from "../../Shared/Constants";
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { userContext } from "../../UserContext";
import { getCollectionName } from "../../Utils/APITypeUtils";
import { isCapabilityEnabled, isServerlessAccount } from "../../Utils/CapabilityUtils";
import { getUpsellMessage } from "../../Utils/PricingUtils";
import { CollectionCreation } from "Shared/Constants";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
import { userContext } from "UserContext";
import { getCollectionName } from "Utils/APITypeUtils";
import { isCapabilityEnabled, isServerlessAccount } from "Utils/CapabilityUtils";
import { getUpsellMessage } from "Utils/PricingUtils";
import { CollapsibleSectionComponent } from "../Controls/CollapsiblePanel/CollapsibleSectionComponent";
import { ThroughputInput } from "../Controls/ThroughputInput/ThroughputInput";
import Explorer from "../Explorer";

View File

@@ -1,14 +1,14 @@
import { Checkbox, Dropdown, IDropdownOption, Link, Stack, Text, TextField } from "@fluentui/react";
import * as Constants from "Common/Constants";
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
import { useSidePanel } from "hooks/useSidePanel";
import React, { FunctionComponent, useState } from "react";
import * as Constants from "../../../Common/Constants";
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
import { InfoTooltip } from "../../../Common/Tooltip/InfoTooltip";
import { useSidePanel } from "../../../hooks/useSidePanel";
import * as SharedConstants from "../../../Shared/Constants";
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
import { userContext } from "../../../UserContext";
import { isServerlessAccount } from "../../../Utils/CapabilityUtils";
import * as SharedConstants from "Shared/Constants";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
import { userContext } from "UserContext";
import { isServerlessAccount } from "Utils/CapabilityUtils";
import { ThroughputInput } from "../../Controls/ThroughputInput/ThroughputInput";
import Explorer from "../../Explorer";
import { CassandraAPIDataClient } from "../../Tables/TableDataClient";

View File

@@ -1,18 +1,18 @@
import { Text, TextField } from "@fluentui/react";
import { Areas } from "Common/Constants";
import { deleteCollection } from "Common/dataAccess/deleteCollection";
import DeleteFeedback from "Common/DeleteFeedback";
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
import { Collection } from "Contracts/ViewModels";
import { useSidePanel } from "hooks/useSidePanel";
import { useTabs } from "hooks/useTabs";
import React, { FunctionComponent, useState } from "react";
import { Areas } from "../../../Common/Constants";
import { deleteCollection } from "../../../Common/dataAccess/deleteCollection";
import DeleteFeedback from "../../../Common/DeleteFeedback";
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
import { Collection } from "../../../Contracts/ViewModels";
import { useSidePanel } from "../../../hooks/useSidePanel";
import { useTabs } from "../../../hooks/useTabs";
import { DefaultExperienceUtility } from "../../../Shared/DefaultExperienceUtility";
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
import { userContext } from "../../../UserContext";
import { getCollectionName } from "../../../Utils/APITypeUtils";
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
import { DefaultExperienceUtility } from "Shared/DefaultExperienceUtility";
import { Action, ActionModifiers } from "Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
import { userContext } from "UserContext";
import { getCollectionName } from "Utils/APITypeUtils";
import * as NotificationConsoleUtils from "Utils/NotificationConsoleUtils";
import { useDatabases } from "../../useDatabases";
import { useSelectedNode } from "../../useSelectedNode";
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";

View File

@@ -1,18 +1,18 @@
import { Text, TextField } from "@fluentui/react";
import { useBoolean } from "@fluentui/react-hooks";
import { Areas } from "Common/Constants";
import { deleteDatabase } from "Common/dataAccess/deleteDatabase";
import DeleteFeedback from "Common/DeleteFeedback";
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
import { Collection, Database } from "Contracts/ViewModels";
import { useSidePanel } from "hooks/useSidePanel";
import { useTabs } from "hooks/useTabs";
import React, { FunctionComponent, useState } from "react";
import { Areas } from "../../Common/Constants";
import { deleteDatabase } from "../../Common/dataAccess/deleteDatabase";
import DeleteFeedback from "../../Common/DeleteFeedback";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
import { Collection, Database } from "../../Contracts/ViewModels";
import { useSidePanel } from "../../hooks/useSidePanel";
import { useTabs } from "../../hooks/useTabs";
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { userContext } from "../../UserContext";
import { logConsoleError } from "../../Utils/NotificationConsoleUtils";
import { DefaultExperienceUtility } from "Shared/DefaultExperienceUtility";
import { Action, ActionModifiers } from "Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
import { userContext } from "UserContext";
import { logConsoleError } from "Utils/NotificationConsoleUtils";
import { useDatabases } from "../useDatabases";
import { useSelectedNode } from "../useSelectedNode";
import { PanelInfoErrorComponent, PanelInfoErrorProps } from "./PanelInfoErrorComponent";

View File

@@ -1,13 +1,13 @@
import { Checkbox, ChoiceGroup, IChoiceGroupOption, SpinButton } from "@fluentui/react";
import * as Constants from "Common/Constants";
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
import { configContext } from "ConfigContext";
import { useSidePanel } from "hooks/useSidePanel";
import React, { FunctionComponent, MouseEvent, useState } from "react";
import * as Constants from "../../../Common/Constants";
import { InfoTooltip } from "../../../Common/Tooltip/InfoTooltip";
import { configContext } from "../../../ConfigContext";
import { useSidePanel } from "../../../hooks/useSidePanel";
import { LocalStorageUtility, StorageKey } from "../../../Shared/StorageUtility";
import * as StringUtility from "../../../Shared/StringUtility";
import { userContext } from "../../../UserContext";
import { logConsoleInfo } from "../../../Utils/NotificationConsoleUtils";
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
import * as StringUtility from "Shared/StringUtility";
import { userContext } from "UserContext";
import { logConsoleInfo } from "Utils/NotificationConsoleUtils";
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
export const SettingsPane: FunctionComponent = () => {

View File

@@ -1,8 +1,8 @@
import { TextField } from "@fluentui/react";
import * as ViewModels from "Contracts/ViewModels";
import { useTabs } from "hooks/useTabs";
import React, { FormEvent, FunctionComponent, useState } from "react";
import * as ViewModels from "../../../Contracts/ViewModels";
import { useTabs } from "../../../hooks/useTabs";
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "Utils/NotificationConsoleUtils";
import * as FileSystemUtil from "../../Notebook/FileSystemUtil";
import { NotebookContentItem } from "../../Notebook/NotebookContentItem";
import NotebookV2Tab from "../../Tabs/NotebookV2Tab";

View File

@@ -1,7 +1,7 @@
import { Upload } from "Common/Upload/Upload";
import { useSidePanel } from "hooks/useSidePanel";
import React, { ChangeEvent, FunctionComponent, useState } from "react";
import { Upload } from "../../../Common/Upload/Upload";
import { useSidePanel } from "../../../hooks/useSidePanel";
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "Utils/NotificationConsoleUtils";
import { NotebookContentItem } from "../../Notebook/NotebookContentItem";
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";

View File

@@ -1,8 +1,8 @@
import { DetailsList, DetailsListLayoutMode, IColumn, SelectionMode } from "@fluentui/react";
import { Upload } from "Common/Upload/Upload";
import { UploadDetailsRecord } from "Contracts/ViewModels";
import React, { ChangeEvent, FunctionComponent, useState } from "react";
import { Upload } from "../../../Common/Upload/Upload";
import { UploadDetailsRecord } from "../../../Contracts/ViewModels";
import { logConsoleError } from "../../../Utils/NotificationConsoleUtils";
import { logConsoleError } from "Utils/NotificationConsoleUtils";
import { getErrorMessage } from "../../Tables/Utilities";
import { useSelectedNode } from "../../useSelectedNode";
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";

View File

@@ -118,7 +118,7 @@ export default class NotebookTabV2 extends NotebookTabBase {
const saveButtonChildren = [];
if (this.container.notebookManager?.gitHubOAuthService.isLoggedIn()) {
saveButtonChildren.push({
iconName: "Copy",
iconName: copyToLabel,
onCommandClick: () => this.copyNotebook(),
commandButtonLabel: copyToLabel,
hasPopup: false,

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-irregular-whitespace */
import { Resource, StoredProcedureDefinition } from "@azure/cosmos";
import * as ko from "knockout";
import * as Constants from "../../Common/Constants";
@@ -16,7 +15,7 @@ import { NewStoredProcedureTab } from "../Tabs/StoredProcedureTab/StoredProcedur
import TabsBase from "../Tabs/TabsBase";
import { useSelectedNode } from "../useSelectedNode";
const sampleStoredProcedureBody = `// SAMPLE STORED PROCEDURE
const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE
function sample(prefix) {
var collection = getContext().getCollection();
@@ -64,8 +63,7 @@ export default class StoredProcedure {
this.isExecuteEnabled = userContext.features.executeSproc;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public static create(source: ViewModels.Collection, _event: MouseEvent): void {
public static create(source: ViewModels.Collection, event: MouseEvent) {
const id = useTabs.getState().getTabs(ViewModels.CollectionTabKind.StoredProcedures).length + 1;
const storedProcedure = <StoredProcedureDefinition>{
id: "",
@@ -91,7 +89,7 @@ export default class StoredProcedure {
useTabs.getState().activateNewTab(storedProcedureTab);
}
public select(): void {
public select() {
useSelectedNode.getState().setSelectedNode(this);
TelemetryProcessor.trace(Action.SelectItem, ActionModifiers.Mark, {
description: "Stored procedure node",
@@ -100,7 +98,7 @@ export default class StoredProcedure {
});
}
public open = (): void => {
public open = () => {
this.select();
const storedProcedureTabs: NewStoredProcedureTab[] = useTabs
@@ -140,7 +138,7 @@ export default class StoredProcedure {
useTabs.getState().activateNewTab(storedProcedureTab);
}
};
public delete(): void {
public delete() {
useDialog.getState().showOkCancelModalDialog(
"Confirm delete",
"Are you sure you want to delete the stored procedure?",
@@ -151,8 +149,7 @@ export default class StoredProcedure {
useTabs.getState().closeTabsByComparator((tab: TabsBase) => tab.node && tab.node.rid === this.rid);
this.collection.children.remove(this);
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
() => {}
(reason) => {}
);
},
"Cancel",

View File

@@ -4,27 +4,28 @@ import * as DataModels from "../../Contracts/DataModels";
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
import { userContext } from "../../UserContext";
export const generateEncryptedToken = async (readOnly = false): Promise<DataModels.GenerateTokenResponse> => {
const url = configContext.BACKEND_ENDPOINT + "/api/tokens/generateToken" + _generateResourceUrl();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const headers: any = { authorization: userContext.authorizationToken };
headers[Constants.HttpHeaders.getReadOnlyKey] = readOnly;
export default class AuthHeadersUtil {
public static async generateEncryptedToken(readOnly: boolean = false): Promise<DataModels.GenerateTokenResponse> {
const url = configContext.BACKEND_ENDPOINT + "/api/tokens/generateToken" + AuthHeadersUtil._generateResourceUrl();
const headers: any = { authorization: userContext.authorizationToken };
headers[Constants.HttpHeaders.getReadOnlyKey] = readOnly;
const response = await fetch(url, { method: "POST", headers });
const result = await response.json();
// This API has a quirk where the response must be parsed to JSON twice
return JSON.parse(result);
};
const response = await fetch(url, { method: "POST", headers });
const result = await response.json();
// This API has a quirk where the response must be parsed to JSON twice
return JSON.parse(result);
}
export const _generateResourceUrl = (): string => {
const { databaseAccount, resourceGroup, subscriptionId } = userContext;
const apiKind: DataModels.ApiKind = DefaultExperienceUtility.getApiKindFromDefaultExperience(userContext.apiType);
const accountEndpoint = databaseAccount?.properties?.documentEndpoint || "";
const sid = subscriptionId || "";
const rg = resourceGroup || "";
const dba = databaseAccount?.name || "";
const resourceUrl = encodeURIComponent(accountEndpoint);
const rid = "";
const rtype = "";
return `?resourceUrl=${resourceUrl}&rid=${rid}&rtype=${rtype}&sid=${sid}&rg=${rg}&dba=${dba}&api=${apiKind}`;
};
private static _generateResourceUrl(): string {
const { databaseAccount, resourceGroup, subscriptionId } = userContext;
const apiKind: DataModels.ApiKind = DefaultExperienceUtility.getApiKindFromDefaultExperience(userContext.apiType);
const accountEndpoint = databaseAccount?.properties?.documentEndpoint || "";
const sid = subscriptionId || "";
const rg = resourceGroup || "";
const dba = databaseAccount?.name || "";
const resourceUrl = encodeURIComponent(accountEndpoint);
const rid = "";
const rtype = "";
return `?resourceUrl=${resourceUrl}&rid=${rid}&rtype=${rtype}&sid=${sid}&rg=${rg}&dba=${dba}&api=${apiKind}`;
}
}

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import { GenerateTokenResponse } from "../Contracts/DataModels";
import * as AuthHeadersUtil from "../Platform/Hosted/Authorization";
import AuthHeadersUtil from "../Platform/Hosted/Authorization";
export function useFullScreenURLs(): GenerateTokenResponse | undefined {
const [state, setState] = useState<GenerateTokenResponse>();

View File

@@ -15,18 +15,13 @@
"target": "es2017",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"lib": [
"es5",
"es6",
"dom"
],
"lib": ["es5", "es6", "dom"],
"jsx": "react",
"moduleResolution": "node",
"resolveJsonModule": true,
"noEmit": true,
"types": [
"jest"
]
"types": ["jest"],
"baseUrl": "src"
},
"typedocOptions": {
"entryPoints": [
@@ -42,11 +37,6 @@
"includes": "./src/SelfServe/Documentation",
"disableSources": true
},
"include": [
"./src/**/*",
"./utils/**/*"
],
"exclude": [
"./src/**/__mocks__/**/*"
]
}
"include": ["src", "./src/**/*", "./utils/**/*"],
"exclude": ["./src/**/__mocks__/**/*"]
}

View File

@@ -227,6 +227,7 @@ module.exports = function (_env = {}, argv = {}) {
rules,
},
resolve: {
modules: [path.resolve(__dirname, "src"), "node_modules"],
alias: {
process: "process/browser",
},