Compare commits

...

5 Commits

Author SHA1 Message Date
sunilyadav840
6d63496aff Merge branch 'master' of https://github.com/Azure/cosmos-explorer into eslint/fix-lint-utility 2021-07-26 18:40:40 +05:30
victor-meng
a8bc821dec Add initializeGitHubRepos function in useNotebooks store (#957) 2021-07-23 18:44:24 -07:00
victor-meng
1394aae944 Fix validateCollectionId for new tables account (#958) 2021-07-23 18:44:16 -07:00
sunilyadav840
cc8614baad fixed format issue 2021-03-04 18:20:15 +05:30
sunilyadav840
fb441cd9ac fixed lint issue of Utilities.ts 2021-03-04 17:15:27 +05:30
5 changed files with 83 additions and 40 deletions

View File

@@ -121,7 +121,6 @@ src/Explorer/Tables/QueryBuilder/QueryBuilderViewModel.ts
src/Explorer/Tables/QueryBuilder/QueryClauseViewModel.ts
src/Explorer/Tables/TableDataClient.ts
src/Explorer/Tables/TableEntityProcessor.ts
src/Explorer/Tables/Utilities.ts
src/Explorer/Tabs/ConflictsTab.ts
src/Explorer/Tabs/DatabaseSettingsTab.ts
src/Explorer/Tabs/DocumentsTab.test.ts

View File

@@ -29,6 +29,7 @@ import { SnapshotRequest } from "./NotebookComponent/types";
import { NotebookContainerClient } from "./NotebookContainerClient";
import { NotebookContentClient } from "./NotebookContentClient";
import { SchemaAnalyzerNotebook } from "./SchemaAnalyzer/SchemaAnalyzerUtils";
import { useNotebook } from "./useNotebook";
type NotebookPaneContent = string | ImmutableNotebook;
@@ -110,6 +111,7 @@ export default class NotebookManager {
this.junoClient.subscribeToPinnedRepos((pinnedRepos) => {
this.params.resourceTree.initializeGitHubRepos(pinnedRepos);
this.params.resourceTree.triggerRender();
useNotebook.getState().initializeGitHubRepos(pinnedRepos);
});
this.refreshPinnedRepos();
}

View File

@@ -6,10 +6,12 @@ import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
import * as Logger from "../../Common/Logger";
import { configContext } from "../../ConfigContext";
import * as DataModels from "../../Contracts/DataModels";
import { IPinnedRepo } from "../../Juno/JunoClient";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { userContext } from "../../UserContext";
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
import * as GitHubUtils from "../../Utils/GitHubUtils";
import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentItem";
import NotebookManager from "./NotebookManager";
@@ -39,6 +41,7 @@ interface NotebookState {
updateNotebookItem: (item: NotebookContentItem) => void;
deleteNotebookItem: (item: NotebookContentItem) => void;
initializeNotebooksTree: (notebookManager: NotebookManager) => Promise<void>;
initializeGitHubRepos: (pinnedRepos: IPinnedRepo[]) => void;
}
export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
@@ -202,4 +205,31 @@ export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
}
}
},
initializeGitHubRepos: (pinnedRepos: IPinnedRepo[]): void => {
const gitHubNotebooksContentRoot = cloneDeep(get().gitHubNotebooksContentRoot);
if (gitHubNotebooksContentRoot) {
gitHubNotebooksContentRoot.children = [];
pinnedRepos?.forEach((pinnedRepo) => {
const repoFullName = GitHubUtils.toRepoFullName(pinnedRepo.owner, pinnedRepo.name);
const repoTreeItem: NotebookContentItem = {
name: repoFullName,
path: "PsuedoDir",
type: NotebookContentItemType.Directory,
children: [],
};
pinnedRepo.branches.forEach((branch) => {
repoTreeItem.children.push({
name: branch.name,
path: GitHubUtils.toContentUri(pinnedRepo.owner, pinnedRepo.name, branch.name, ""),
type: NotebookContentItemType.Directory,
});
});
gitHubNotebooksContentRoot.children.push(repoTreeItem);
});
set({ gitHubNotebooksContentRoot });
}
},
}));

View File

@@ -1,3 +1,8 @@
/**
* [Todo] disable any type of file.
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as _ from "underscore";
import Q from "q";
import * as Entities from "./Entities";
@@ -8,11 +13,11 @@ import * as Constants from "./Constants";
* Generates a pseudo-random GUID.
*/
export function guid() {
function s4() {
const s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
};
return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();
}
@@ -39,7 +44,7 @@ export function ensureBetweenBounds(value: number, minimum: number, maximum: num
* If supplied, the original error will be added as "details".
*/
export function getErrorMessage(error: any, simpleMessage?: string): string {
var detailsMessage: string;
let detailsMessage: string;
if (typeof error === "string" || error instanceof String) {
detailsMessage = error.toString();
} else {
@@ -59,7 +64,7 @@ export function getErrorMessage(error: any, simpleMessage?: string): string {
* Get the environment's new line characters
*/
export function getEnvironmentNewLine(): string {
var platform = navigator.platform.toUpperCase();
const platform = navigator.platform.toUpperCase();
if (platform.indexOf("WIN") >= 0) {
return "\r\n";
@@ -73,7 +78,7 @@ export function getEnvironmentNewLine(): string {
* Tests whether two arrays have same elements in the same sequence.
*/
export function isEqual<T>(a: T[], b: T[]): boolean {
var isEqual: boolean = false;
let isEqual = false;
if (!!a && !!b && a.length === b.length) {
isEqual = _.every(a, (value: T, index: number) => value === b[index]);
}
@@ -85,12 +90,13 @@ export function isEqual<T>(a: T[], b: T[]): boolean {
*/
export function jQuerySelectorEscape(value: string): string {
value = value || "";
return value.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, "\\$&");
// removed Unnecessary escape character: \/.eslintno-useless-escape
return value.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
}
export function copyTableQuery(query: Entities.ITableQuery): Entities.ITableQuery {
if (!query) {
return null;
return undefined;
}
return {
@@ -104,7 +110,7 @@ export function copyTableQuery(query: Entities.ITableQuery): Entities.ITableQuer
* Html encode
*/
export function htmlEncode(value: string): string {
var _divElem: JQuery = $("<div/>");
const _divElem: JQuery = $("<div/>");
return _divElem.text(value).html();
}
@@ -117,22 +123,22 @@ export function onKey(
event: any,
eventKeyCode: number,
action: ($sourceElement: JQuery) => void,
metaKey: boolean = null,
shiftKey: boolean = null,
altKey: boolean = null
metaKey?: boolean,
shiftKey?: boolean,
altKey?: boolean
): boolean {
var source: any = event.target || event.srcElement,
const source: unknown = event.target || event.srcElement,
keyCode: number = event.keyCode,
$sourceElement = $(source),
handled: boolean = false;
$sourceElement = $(source);
let handled = false;
if (
$sourceElement.length &&
keyCode === eventKeyCode &&
$.isFunction(action) &&
(metaKey === null || metaKey === event.metaKey) &&
(shiftKey === null || shiftKey === event.shiftKey) &&
(altKey === null || altKey === event.altKey)
(metaKey === undefined || metaKey === event.metaKey) &&
(shiftKey === undefined || shiftKey === event.shiftKey) &&
(altKey === undefined || altKey === event.altKey)
) {
action($sourceElement);
handled = true;
@@ -147,9 +153,9 @@ export function onKey(
export function onEnter(
event: any,
action: ($sourceElement: JQuery) => void,
metaKey: boolean = null,
shiftKey: boolean = null,
altKey: boolean = null
metaKey?: boolean,
shiftKey?: boolean,
altKey?: boolean
): boolean {
return onKey(event, Constants.keyCodes.Enter, action, metaKey, shiftKey, altKey);
}
@@ -160,9 +166,9 @@ export function onEnter(
export function onTab(
event: any,
action: ($sourceElement: JQuery) => void,
metaKey: boolean = null,
shiftKey: boolean = null,
altKey: boolean = null
metaKey?: boolean,
shiftKey?: boolean,
altKey?: boolean
): boolean {
return onKey(event, Constants.keyCodes.Tab, action, metaKey, shiftKey, altKey);
}
@@ -173,9 +179,9 @@ export function onTab(
export function onEsc(
event: any,
action: ($sourceElement: JQuery) => void,
metaKey: boolean = null,
shiftKey: boolean = null,
altKey: boolean = null
metaKey?: boolean,
shiftKey?: boolean,
altKey?: boolean
): boolean {
return onKey(event, Constants.keyCodes.Esc, action, metaKey, shiftKey, altKey);
}
@@ -200,21 +206,21 @@ export function isEnvironmentAltPressed(event: JQueryEventObject): boolean {
* Returns whether the current platform is MacOS.
*/
export function isMac(): boolean {
var platform = navigator.platform.toUpperCase();
const platform = navigator.platform.toUpperCase();
return platform.indexOf("MAC") >= 0;
}
// MAX_SAFE_INTEGER and MIN_SAFE_INTEGER will be provided by ECMAScript 6's Number
export var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
export var MIN_SAFE_INTEGER = -MAX_SAFE_INTEGER;
export const MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
export const MIN_SAFE_INTEGER = -MAX_SAFE_INTEGER;
/**
* Tests whether a value a safe integer.
* A safe integer is an integer that can be exactly represented as an IEEE-754 double precision number (all integers from (2^53 - 1) to -(2^53 - 1))
* Note: Function and constants will be provided by ECMAScript 6's Number.
*/
export function isSafeInteger(value: any): boolean {
var n: number = typeof value !== "number" ? Number(value) : value;
export function isSafeInteger(value: number | string): boolean {
const n: number = typeof value !== "number" ? Number(value) : value;
return Math.round(n) === n && MIN_SAFE_INTEGER <= n && n <= MAX_SAFE_INTEGER;
}
@@ -240,7 +246,7 @@ export function getInputTypeFromDisplayedName(displayedName: string): string {
}
export function padLongWithZeros(value: string): string {
var s = "0000000000000000000" + value;
const s = "0000000000000000000" + value;
return s.substr(s.length - 20);
}
@@ -249,13 +255,13 @@ export function padLongWithZeros(value: string): string {
* Notice: Not every header will have a data type since some headers don't even exist in entities.
*/
export function getDataTypesFromEntities(headers: string[], entities: Entities.ITableEntity[]): any {
var currentHeaders: string[] = _.clone(headers);
var dataTypes: any = {};
let currentHeaders: string[] = _.clone(headers);
const dataTypes: any = {};
entities = entities || [];
entities.forEach((entity: Entities.ITableEntity, index: number) => {
entities.forEach((entity: Entities.ITableEntity) => {
if (currentHeaders.length) {
var keys: string[] = _.keys(entity);
var headersToProcess: string[] = _.intersection(currentHeaders, keys);
const keys: string[] = _.keys(entity);
const headersToProcess: string[] = _.intersection(currentHeaders, keys);
headersToProcess &&
headersToProcess.forEach((propertyName: string) => {
dataTypes[propertyName] = entity[propertyName].$ || Constants.TableType.String;
@@ -270,9 +276,9 @@ export function getDataTypesFromEntities(headers: string[], entities: Entities.I
* Set a data type for each header. The data type is inferred from Cassandra Schema.
*/
export function getDataTypesFromCassandraSchema(schema: CassandraTableKey[]): any {
var dataTypes: any = {};
const dataTypes: any = {};
schema &&
schema.forEach((schemaItem: CassandraTableKey, index: number) => {
schema.forEach((schemaItem: CassandraTableKey) => {
dataTypes[schemaItem.property] = schemaItem.type;
});
return dataTypes;

View File

@@ -2,6 +2,7 @@ import _ from "underscore";
import create, { UseStore } from "zustand";
import * as Constants from "../Common/Constants";
import * as ViewModels from "../Contracts/ViewModels";
import { userContext } from "../UserContext";
import { useSelectedNode } from "./useSelectedNode";
interface DatabasesState {
@@ -136,6 +137,11 @@ export const useDatabases: UseStore<DatabasesState> = create((set, get) => ({
},
validateCollectionId: async (databaseId: string, collectionId: string): Promise<boolean> => {
const database = get().databases.find((db) => db.id() === databaseId);
// For a new tables account, database is undefined when creating the first table
if (!database && userContext.apiType === "Tables") {
return true;
}
await database.loadCollections();
return !database.collections().some((collection) => collection.id() === collectionId);
},