mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-24 19:31:36 +00:00
Compare commits
3 Commits
resolve_De
...
fix_eslint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dc879b753 | ||
|
|
1ce8d077d5 | ||
|
|
271256bffb |
@@ -68,31 +68,23 @@ src/Explorer/Notebook/NotebookComponent/reducers.ts
|
||||
src/Explorer/Notebook/NotebookComponent/store.ts
|
||||
src/Explorer/Notebook/NotebookComponent/types.ts
|
||||
src/Explorer/Notebook/NotebookContainerClient.ts
|
||||
src/Explorer/Notebook/NotebookContentClient.ts
|
||||
src/Explorer/Notebook/NotebookContentItem.ts
|
||||
src/Explorer/Notebook/NotebookUtil.ts
|
||||
src/Explorer/OpenActionsStubs.ts
|
||||
src/Explorer/Panes/Tables/Validators/EntityPropertyNameValidator.ts
|
||||
src/Explorer/Panes/Tables/Validators/EntityPropertyValidationCommon.ts
|
||||
src/Explorer/Panes/Tables/Validators/EntityPropertyValueValidator.ts
|
||||
src/Explorer/SplashScreen/SplashScreen.test.ts
|
||||
src/Explorer/Tables/DataTable/CacheBase.ts
|
||||
src/Explorer/Tables/DataTable/DataTableBindingManager.ts
|
||||
src/Explorer/Tables/DataTable/DataTableBuilder.ts
|
||||
src/Explorer/Tables/DataTable/DataTableContextMenu.ts
|
||||
src/Explorer/Tables/DataTable/DataTableOperationManager.ts
|
||||
# src/Explorer/Tables/DataTable/DataTableOperations.ts
|
||||
src/Explorer/Tables/DataTable/DataTableViewModel.ts
|
||||
# src/Explorer/Tables/DataTable/TableCommands.ts
|
||||
# src/Explorer/Tables/DataTable/TableEntityCache.ts
|
||||
src/Explorer/Tables/DataTable/TableEntityListViewModel.ts
|
||||
# src/Explorer/Tables/Entities.ts
|
||||
src/Explorer/Tables/QueryBuilder/CustomTimestampHelper.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
|
||||
src/Explorer/Tabs/DocumentsTab.ts
|
||||
src/Explorer/Tabs/GraphTab.ts
|
||||
src/Explorer/Tabs/MongoDocumentsTab.ts
|
||||
@@ -117,6 +109,8 @@ src/Index.ts
|
||||
src/Platform/Hosted/Authorization.ts
|
||||
src/ReactDevTools.ts
|
||||
src/Shared/Constants.ts
|
||||
src/Shared/DefaultExperienceUtility.test.ts
|
||||
src/Shared/DefaultExperienceUtility.ts
|
||||
src/Shared/appInsights.ts
|
||||
src/SparkClusterManager/ArcadiaResourceManager.ts
|
||||
src/SparkClusterManager/SparkClusterManager.ts
|
||||
@@ -131,20 +125,13 @@ src/Explorer/Controls/Notebook/NotebookTerminalComponent.tsx
|
||||
src/Explorer/Controls/NotebookViewer/NotebookViewerComponent.tsx
|
||||
src/Explorer/Controls/TreeComponent/TreeComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/GraphExplorer.test.tsx
|
||||
; src/Explorer/Graph/GraphExplorerComponent/GraphExplorer.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/GraphVizComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/LeftPaneComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/MiddlePaneComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/NodePropertiesComponent.test.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/NodePropertiesComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/ReadOnlyNodePropertiesComponent.test.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/ReadOnlyNodePropertiesComponent.tsx
|
||||
src/Explorer/Menus/CommandBar/CommandBarUtil.tsx
|
||||
src/Explorer/Notebook/NotebookComponent/NotebookComponentAdapter.tsx
|
||||
; src/Explorer/Notebook/NotebookComponent/NotebookComponentBootstrapper.tsx
|
||||
src/Explorer/Notebook/NotebookComponent/VirtualCommandBarComponent.tsx
|
||||
src/Explorer/Notebook/NotebookComponent/contents/index.tsx
|
||||
; src/Explorer/Notebook/NotebookRenderer/NotebookReadOnlyRenderer.tsx
|
||||
src/Explorer/Notebook/NotebookRenderer/NotebookRenderer.tsx
|
||||
src/Explorer/Notebook/NotebookRenderer/decorators/draggable/index.tsx
|
||||
src/Explorer/Notebook/NotebookRenderer/decorators/hijack-scroll/index.tsx
|
||||
|
||||
@@ -58,7 +58,7 @@ export class LeftPaneComponent extends React.Component<LeftPaneComponentProps> {
|
||||
className={className}
|
||||
as="tr"
|
||||
aria-label={node.caption}
|
||||
onActivated={(e) => this.props.onRootNodeSelected(node.id)}
|
||||
onActivated={() => this.props.onRootNodeSelected(node.id)}
|
||||
key={node.id}
|
||||
>
|
||||
<td className="resultItem">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from "react";
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import * as Q from "q";
|
||||
import { NodePropertiesComponent, NodePropertiesComponentProps, Mode } from "./NodePropertiesComponent";
|
||||
import { GraphHighlightedNodeData, EditedProperties, EditedEdges, PossibleVertex } from "./GraphExplorer";
|
||||
import React from "react";
|
||||
import { GraphHighlightedNodeData, PossibleVertex } from "./GraphExplorer";
|
||||
import { Mode, NodePropertiesComponent, NodePropertiesComponentProps } from "./NodePropertiesComponent";
|
||||
|
||||
describe("Property pane", () => {
|
||||
const title = "My Title";
|
||||
@@ -37,17 +37,18 @@ describe("Property pane", () => {
|
||||
return {
|
||||
expandedTitle: title,
|
||||
isCollapsed: false,
|
||||
onCollapsedChanged: (newValue: boolean): void => {},
|
||||
onCollapsedChanged: jest.fn(),
|
||||
node: highlightedNode,
|
||||
getPkIdFromNodeData: (v: GraphHighlightedNodeData): string => null,
|
||||
collectionPartitionKeyProperty: null,
|
||||
updateVertexProperties: (editedProperties: EditedProperties): Q.Promise<void> => Q.resolve(),
|
||||
selectNode: (id: string): void => {},
|
||||
updatePossibleVertices: (): Q.Promise<PossibleVertex[]> => Q.resolve(null),
|
||||
possibleEdgeLabels: null,
|
||||
editGraphEdges: (editedEdges: EditedEdges): Q.Promise<any> => Q.resolve(),
|
||||
deleteHighlightedNode: (): void => {},
|
||||
onModeChanged: (newMode: Mode): void => {},
|
||||
getPkIdFromNodeData: (): string => undefined,
|
||||
collectionPartitionKeyProperty: undefined,
|
||||
updateVertexProperties: (): Q.Promise<void> => Q.resolve(),
|
||||
selectNode: jest.fn(),
|
||||
updatePossibleVertices: (): Q.Promise<PossibleVertex[]> => Q.resolve(undefined),
|
||||
possibleEdgeLabels: undefined,
|
||||
//eslint-disable-next-line
|
||||
editGraphEdges: (): Q.Promise<any> => Q.resolve(),
|
||||
deleteHighlightedNode: jest.fn(),
|
||||
onModeChanged: jest.fn(),
|
||||
viewMode: Mode.READONLY_PROP,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ export class NodePropertiesComponent extends React.Component<
|
||||
super(props);
|
||||
this.state = {
|
||||
editedProperties: {
|
||||
pkId: null,
|
||||
pkId: undefined,
|
||||
readOnlyProperties: [],
|
||||
existingProperties: [],
|
||||
addedProperties: [],
|
||||
@@ -98,15 +98,12 @@ export class NodePropertiesComponent extends React.Component<
|
||||
};
|
||||
}
|
||||
|
||||
public static getDerivedStateFromProps(
|
||||
props: NodePropertiesComponentProps,
|
||||
state: NodePropertiesComponentState
|
||||
): Partial<NodePropertiesComponentState> {
|
||||
public static getDerivedStateFromProps(props: NodePropertiesComponentProps): Partial<NodePropertiesComponentState> {
|
||||
if (props.viewMode !== Mode.READONLY_PROP) {
|
||||
return { isDeleteConfirm: false };
|
||||
}
|
||||
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
@@ -138,10 +135,10 @@ export class NodePropertiesComponent extends React.Component<
|
||||
* @param value
|
||||
*/
|
||||
private static getTypeOption(value: any): ViewModels.InputPropertyValueTypeString {
|
||||
if (value == null) {
|
||||
if (value === undefined) {
|
||||
return "null";
|
||||
}
|
||||
let type = typeof value;
|
||||
const type = typeof value;
|
||||
switch (type) {
|
||||
case "number":
|
||||
case "boolean":
|
||||
@@ -172,10 +169,9 @@ export class NodePropertiesComponent extends React.Component<
|
||||
];
|
||||
|
||||
const existingProps: ViewModels.InputProperty[] = [];
|
||||
|
||||
if (this.props.node.hasOwnProperty("properties")) {
|
||||
const hProps = this.props.node["properties"];
|
||||
for (let p in hProps) {
|
||||
for (const p in hProps) {
|
||||
const propValues = hProps[p];
|
||||
(p === partitionKeyProperty ? readOnlyProps : existingProps).push({
|
||||
key: p,
|
||||
@@ -437,7 +433,7 @@ export class NodePropertiesComponent extends React.Component<
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,11 +228,12 @@ export class NotebookContentClient {
|
||||
|
||||
public async readFileContent(filePath: string): Promise<string> {
|
||||
const xhr = await this.contentProvider.get(this.getServerConfig(), filePath, { content: 1 }).toPromise();
|
||||
//eslint-disable-next-line
|
||||
const content = (xhr.response as any).content;
|
||||
if (!content) {
|
||||
throw new Error("No content read");
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
const format = (xhr.response as any).format;
|
||||
switch (format) {
|
||||
case "text":
|
||||
|
||||
@@ -12,6 +12,7 @@ import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentI
|
||||
// Must match rx-jupyter' FileType
|
||||
export type FileType = "directory" | "file" | "notebook";
|
||||
// Utilities for notebooks
|
||||
//eslint-disable-next-line
|
||||
export class NotebookUtil {
|
||||
public static UntrustedNotebookRunHint = "Please trust notebook first before running any code cells";
|
||||
|
||||
@@ -190,6 +191,7 @@ export class NotebookUtil {
|
||||
subSnapshots: SnapshotFragment[],
|
||||
downloadFilename?: string
|
||||
): Promise<{ imageSrc: string | undefined }> => {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
// target.scrollIntoView();
|
||||
@@ -258,6 +260,7 @@ export class NotebookUtil {
|
||||
subSnapshots: SnapshotFragment[],
|
||||
downloadFilename?: string
|
||||
): Promise<{ imageSrc?: string }> => {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve, reject) => {
|
||||
// target.scrollIntoView();
|
||||
try {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Collection } from "Contracts/ViewModels";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import React, { FunctionComponent, useState } from "react";
|
||||
import * as DefaultExperienceUtility from "Shared/DefaultExperienceUtility";
|
||||
import { DefaultExperienceUtility } from "Shared/DefaultExperienceUtility";
|
||||
import { Action, ActionModifiers } from "Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Collection, Database } from "Contracts/ViewModels";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import React, { FunctionComponent, useState } from "react";
|
||||
import * as DefaultExperienceUtility from "Shared/DefaultExperienceUtility";
|
||||
import { DefaultExperienceUtility } from "Shared/DefaultExperienceUtility";
|
||||
import { Action, ActionModifiers } from "Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
import * as ko from "knockout";
|
||||
import * as _ from "underscore";
|
||||
|
||||
import QueryTablesTab from "../../Tabs/QueryTablesTab";
|
||||
import * as Constants from "../Constants";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import * as Entities from "../Entities";
|
||||
import * as Utilities from "../Utilities";
|
||||
import * as DataTableBuilder from "./DataTableBuilder";
|
||||
import DataTableOperationManager from "./DataTableOperationManager";
|
||||
import * as DataTableOperations from "./DataTableOperations";
|
||||
import QueryTablesTab from "../../Tabs/QueryTablesTab";
|
||||
import TableEntityListViewModel from "./TableEntityListViewModel";
|
||||
import * as Utilities from "../Utilities";
|
||||
import * as Entities from "../Entities";
|
||||
|
||||
/**
|
||||
* Custom binding manager of datatable
|
||||
*/
|
||||
var tableEntityListViewModelMap: {
|
||||
const tableEntityListViewModelMap: {
|
||||
[key: string]: {
|
||||
tableViewModel: TableEntityListViewModel;
|
||||
operationManager: DataTableOperationManager;
|
||||
@@ -22,12 +20,13 @@ var tableEntityListViewModelMap: {
|
||||
};
|
||||
} = {};
|
||||
|
||||
function bindDataTable(element: any, valueAccessor: any, allBindings: any, viewModel: any, bindingContext: any) {
|
||||
var tableEntityListViewModel = bindingContext.$data;
|
||||
//eslint-disable-next-line
|
||||
function bindDataTable(element: any, bindingContext: any) {
|
||||
const tableEntityListViewModel = bindingContext.$data;
|
||||
tableEntityListViewModel.notifyColumnChanges = onTableColumnChange;
|
||||
var $dataTable = $(element);
|
||||
var queryTablesTab = bindingContext.$parent;
|
||||
var operationManager = new DataTableOperationManager(
|
||||
const $dataTable = $(element);
|
||||
const queryTablesTab = bindingContext.$parent;
|
||||
const operationManager = new DataTableOperationManager(
|
||||
$dataTable,
|
||||
tableEntityListViewModel,
|
||||
queryTablesTab.tableCommands
|
||||
@@ -44,9 +43,9 @@ function bindDataTable(element: any, valueAccessor: any, allBindings: any, viewM
|
||||
operationManager.focusTable(); // Also selects the first row if needed.
|
||||
}
|
||||
|
||||
function onTableColumnChange(enablePrompt: boolean = true, queryTablesTab: QueryTablesTab) {
|
||||
var columnsFilter: boolean[] = null;
|
||||
var tableEntityListViewModel = tableEntityListViewModelMap[queryTablesTab.tabId].tableViewModel;
|
||||
function onTableColumnChange(queryTablesTab: QueryTablesTab) {
|
||||
const columnsFilter: boolean[] = null;
|
||||
const tableEntityListViewModel = tableEntityListViewModelMap[queryTablesTab.tabId].tableViewModel;
|
||||
if (queryTablesTab.queryViewModel()) {
|
||||
queryTablesTab.queryViewModel().queryBuilderViewModel().updateColumnOptions();
|
||||
}
|
||||
@@ -63,35 +62,36 @@ function createDataTable(
|
||||
startIndex: number,
|
||||
tableEntityListViewModel: TableEntityListViewModel,
|
||||
queryTablesTab: QueryTablesTab,
|
||||
destroy: boolean = false,
|
||||
destroy = false,
|
||||
columnsFilter: boolean[] = null
|
||||
): void {
|
||||
var $dataTable = tableEntityListViewModelMap[queryTablesTab.tabId].$dataTable;
|
||||
const $dataTable = tableEntityListViewModelMap[queryTablesTab.tabId].$dataTable;
|
||||
if (destroy) {
|
||||
// Find currently displayed columns.
|
||||
var currentColumns: string[] = tableEntityListViewModel.headers;
|
||||
const currentColumns: string[] = tableEntityListViewModel.headers;
|
||||
|
||||
// Calculate how many more columns need to added to the current table.
|
||||
var columnsToAdd: number = _.difference(tableEntityListViewModel.headers, currentColumns).length;
|
||||
const columnsToAdd: number = _.difference(tableEntityListViewModel.headers, currentColumns).length;
|
||||
|
||||
// This is needed as current solution of adding column is more like a workaround
|
||||
// The official support for dynamically add column is not yet there
|
||||
// Please track github issue https://github.com/DataTables/DataTables/issues/273 for its offical support
|
||||
for (var i = 0; i < columnsToAdd; i++) {
|
||||
for (let i = 0; i < columnsToAdd; i++) {
|
||||
$(".dataTables_scrollHead table thead tr th").eq(0).after("<th></th>");
|
||||
}
|
||||
tableEntityListViewModel.table.destroy();
|
||||
$dataTable.empty();
|
||||
}
|
||||
|
||||
var jsonColTable = [];
|
||||
const jsonColTable = [];
|
||||
|
||||
for (var i = 0; i < tableEntityListViewModel.headers.length; i++) {
|
||||
for (let i = 0; i < tableEntityListViewModel.headers.length; i++) {
|
||||
jsonColTable.push({
|
||||
sTitle: tableEntityListViewModel.headers[i],
|
||||
data: tableEntityListViewModel.headers[i],
|
||||
aTargets: [i],
|
||||
mRender: bindColumn,
|
||||
// eslint-disable-next-line no-extra-boolean-cast
|
||||
visible: !!columnsFilter ? columnsFilter[i] : true,
|
||||
});
|
||||
}
|
||||
@@ -154,9 +154,10 @@ function createDataTable(
|
||||
table.setAttribute("summary", `Results for container ${tableEntityListViewModel.queryTablesTab.collection.id()}`);
|
||||
});
|
||||
}
|
||||
|
||||
function bindColumn(data: any, type: string, full: any) {
|
||||
var displayedValue: any = null;
|
||||
//eslint-disable-next-line
|
||||
function bindColumn(data: any) {
|
||||
//eslint-disable-next-line
|
||||
let displayedValue: any = null;
|
||||
if (data) {
|
||||
displayedValue = data._;
|
||||
|
||||
@@ -173,7 +174,7 @@ function bindColumn(data: any, type: string, full: any) {
|
||||
}
|
||||
return displayedValue;
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
function getServerData(sSource: any, aoData: any, fnCallback: any, oSettings: any) {
|
||||
tableEntityListViewModelMap[oSettings.ajax].tableViewModel.renderNextPageAndupdateCache(
|
||||
sSource,
|
||||
@@ -191,15 +192,15 @@ function bindClientId(nRow: Node, aData: Entities.ITableEntity) {
|
||||
$(nRow).attr(Constants.htmlAttributeNames.dataTableRowKeyAttr, aData.RowKey._);
|
||||
return nRow;
|
||||
}
|
||||
|
||||
function selectionChanged(element: any, valueAccessor: any, allBindings: any, viewModel: any, bindingContext: any) {
|
||||
//eslint-disable-next-line
|
||||
function selectionChanged(bindingContext: any) {
|
||||
$(".dataTable tr.selected").attr("tabindex", "-1").removeClass("selected");
|
||||
|
||||
const selected =
|
||||
bindingContext && bindingContext.$data && bindingContext.$data.selected && bindingContext.$data.selected();
|
||||
selected &&
|
||||
selected.forEach((b: Entities.ITableEntity) => {
|
||||
var sel = DataTableOperations.getRowSelector([
|
||||
const sel = DataTableOperations.getRowSelector([
|
||||
{
|
||||
key: Constants.htmlAttributeNames.dataTableRowKeyAttr,
|
||||
value: b.RowKey && b.RowKey._ && b.RowKey._.toString(),
|
||||
@@ -211,7 +212,7 @@ function selectionChanged(element: any, valueAccessor: any, allBindings: any, vi
|
||||
//selected = bindingContext.$data.selected();
|
||||
}
|
||||
|
||||
function dataChanged(element: any, valueAccessor: any, allBindings: any, viewModel: any, bindingContext: any) {
|
||||
function dataChanged() {
|
||||
// do nothing for now
|
||||
}
|
||||
|
||||
@@ -229,20 +230,21 @@ function updateTableScrollableRegionMetrics(): void {
|
||||
* Update the table's scrollable region height. So the pagination control is always shown at the bottom of the page.
|
||||
*/
|
||||
function updateTableScrollableRegionHeight(): void {
|
||||
$(".tab-pane").each(function (index, tabElement) {
|
||||
$(".tab-pane").each((index, tabElement) => {
|
||||
if (!$(tabElement).hasClass("tableContainer")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add some padding to the table so it doesn't get too close to the container border.
|
||||
var dataTablePaddingBottom = 10;
|
||||
var bodyHeight = $(window).height();
|
||||
var dataTablesScrollBodyPosY = $(tabElement).find(Constants.htmlSelectors.dataTableScrollBodySelector).offset().top;
|
||||
var dataTablesInfoElem = $(tabElement).find(".dataTables_info");
|
||||
var dataTablesPaginateElem = $(tabElement).find(".dataTables_paginate");
|
||||
const dataTablePaddingBottom = 10;
|
||||
const bodyHeight = $(window).height();
|
||||
const dataTablesScrollBodyPosY = $(tabElement).find(Constants.htmlSelectors.dataTableScrollBodySelector).offset()
|
||||
.top;
|
||||
const dataTablesInfoElem = $(tabElement).find(".dataTables_info");
|
||||
const dataTablesPaginateElem = $(tabElement).find(".dataTables_paginate");
|
||||
const notificationConsoleHeight = 32; /** Header height **/
|
||||
|
||||
var scrollHeight =
|
||||
let scrollHeight =
|
||||
bodyHeight -
|
||||
dataTablesScrollBodyPosY -
|
||||
dataTablesPaginateElem.outerHeight(true) -
|
||||
@@ -257,10 +259,10 @@ function updateTableScrollableRegionHeight(): void {
|
||||
// TODO This is a work around for setting the outerheight since we don't have access to the JQuery.outerheight(numberValue)
|
||||
// in the current version of JQuery we are using. Ideally, we would upgrade JQuery and use this line instead:
|
||||
// $(Constants.htmlSelectors.dataTableScrollBodySelector).outerHeight(scrollHeight);
|
||||
var element = $(tabElement).find(Constants.htmlSelectors.dataTableScrollBodySelector)[0];
|
||||
var style = getComputedStyle(element);
|
||||
var actualHeight = parseInt(style.height);
|
||||
var change = element.offsetHeight - scrollHeight;
|
||||
const element = $(tabElement).find(Constants.htmlSelectors.dataTableScrollBodySelector)[0];
|
||||
const style = getComputedStyle(element);
|
||||
const actualHeight = parseInt(style.height);
|
||||
const change = element.offsetHeight - scrollHeight;
|
||||
$(tabElement)
|
||||
.find(Constants.htmlSelectors.dataTableScrollBodySelector)
|
||||
.height(actualHeight - change);
|
||||
@@ -271,15 +273,15 @@ function updateTableScrollableRegionHeight(): void {
|
||||
* Update the table's scrollable region width to make efficient use of the remaining space.
|
||||
*/
|
||||
function updateTableScrollableRegionWidth(): void {
|
||||
$(".tab-pane").each(function (index, tabElement) {
|
||||
$(".tab-pane").each((index, tabElement) => {
|
||||
if (!$(tabElement).hasClass("tableContainer")) {
|
||||
return;
|
||||
}
|
||||
|
||||
var bodyWidth = $(window).width();
|
||||
var dataTablesScrollBodyPosLeft = $(tabElement).find(Constants.htmlSelectors.dataTableScrollBodySelector).offset()
|
||||
const bodyWidth = $(window).width();
|
||||
const dataTablesScrollBodyPosLeft = $(tabElement).find(Constants.htmlSelectors.dataTableScrollBodySelector).offset()
|
||||
.left;
|
||||
var scrollWidth = bodyWidth - dataTablesScrollBodyPosLeft;
|
||||
const scrollWidth = bodyWidth - dataTablesScrollBodyPosLeft;
|
||||
|
||||
// jquery datatables automatically sets width:100% to both the header and the body when we use it's column autoWidth feature.
|
||||
// We work around that by setting the height for it's container instead.
|
||||
@@ -288,9 +290,9 @@ function updateTableScrollableRegionWidth(): void {
|
||||
}
|
||||
|
||||
function initializeEventHandlers(): void {
|
||||
var $headers: JQuery = $(Constants.htmlSelectors.dataTableHeaderTypeSelector);
|
||||
var $firstHeader: JQuery = $headers.first();
|
||||
var firstIndex: string = $firstHeader.attr(Constants.htmlAttributeNames.dataTableHeaderIndex);
|
||||
const $headers: JQuery = $(Constants.htmlSelectors.dataTableHeaderTypeSelector);
|
||||
const $firstHeader: JQuery = $headers.first();
|
||||
const firstIndex: string = $firstHeader.attr(Constants.htmlAttributeNames.dataTableHeaderIndex);
|
||||
|
||||
$headers
|
||||
.on("keydown", (event: JQueryEventObject) => {
|
||||
@@ -302,7 +304,7 @@ function initializeEventHandlers(): void {
|
||||
Utilities.onTab(
|
||||
event,
|
||||
($sourceElement: JQuery) => {
|
||||
var sourceIndex: string = $sourceElement.attr(Constants.htmlAttributeNames.dataTableHeaderIndex);
|
||||
const sourceIndex: string = $sourceElement.attr(Constants.htmlAttributeNames.dataTableHeaderIndex);
|
||||
|
||||
if (sourceIndex === firstIndex) {
|
||||
event.preventDefault();
|
||||
@@ -324,14 +326,14 @@ function initializeEventHandlers(): void {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
function updateSelectionStatus(oSettings: any): void {
|
||||
var $dataTableRows: JQuery = $(Constants.htmlSelectors.dataTableAllRowsSelector);
|
||||
const $dataTableRows: JQuery = $(Constants.htmlSelectors.dataTableAllRowsSelector);
|
||||
if ($dataTableRows) {
|
||||
for (var i = 0; i < $dataTableRows.length; i++) {
|
||||
var $row: JQuery = $dataTableRows.eq(i);
|
||||
var rowKey: string = $row.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr);
|
||||
var table = tableEntityListViewModelMap[oSettings.ajax].tableViewModel;
|
||||
for (let i = 0; i < $dataTableRows.length; i++) {
|
||||
const $row: JQuery = $dataTableRows.eq(i);
|
||||
const rowKey: string = $row.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr);
|
||||
const table = tableEntityListViewModelMap[oSettings.ajax].tableViewModel;
|
||||
if (table.isItemSelected(table.getTableEntityKeys(rowKey))) {
|
||||
$row.attr("tabindex", "0");
|
||||
}
|
||||
@@ -346,10 +348,10 @@ function updateSelectionStatus(oSettings: any): void {
|
||||
// TODO consider centralizing this "post-command" logic into some sort of Command Manager entity.
|
||||
// See VSO:166520: "[Storage Explorer] Consider adding a 'command manager' to track command post-effects."
|
||||
function updateDataTableFocus(queryTablesTabId: string): void {
|
||||
var $activeElement: JQuery = $(document.activeElement);
|
||||
var isFocusLost: boolean = $activeElement.is("body"); // When focus is lost, "body" becomes the active element.
|
||||
var storageExplorerFrameHasFocus: boolean = document.hasFocus();
|
||||
var operationManager = tableEntityListViewModelMap[queryTablesTabId].operationManager;
|
||||
const $activeElement: JQuery = $(document.activeElement);
|
||||
const isFocusLost: boolean = $activeElement.is("body"); // When focus is lost, "body" becomes the active element.
|
||||
const storageExplorerFrameHasFocus: boolean = document.hasFocus();
|
||||
const operationManager = tableEntityListViewModelMap[queryTablesTabId].operationManager;
|
||||
if (operationManager) {
|
||||
if (isFocusLost && storageExplorerFrameHasFocus) {
|
||||
// We get here when no control is active, meaning that the table update was triggered
|
||||
@@ -371,19 +373,20 @@ function updateDataTableFocus(queryTablesTabId: string): void {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
(<any>ko.bindingHandlers).tableSource = {
|
||||
init: bindDataTable,
|
||||
update: dataChanged,
|
||||
};
|
||||
|
||||
//eslint-disable-next-line
|
||||
(<any>ko.bindingHandlers).tableSelection = {
|
||||
update: selectionChanged,
|
||||
};
|
||||
|
||||
//eslint-disable-next-line
|
||||
(<any>ko.bindingHandlers).readOnly = {
|
||||
update: function (element: any, valueAccessor: any) {
|
||||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||||
//eslint-disable-next-line
|
||||
update: (element: any, valueAccessor: any) => {
|
||||
const value = ko.utils.unwrapObservable(valueAccessor());
|
||||
if (value) {
|
||||
element.setAttribute("readOnly", true);
|
||||
} else {
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as Utilities from "../Utilities";
|
||||
* @param{$dataTableElem} JQuery data table element
|
||||
* @param{$settings} Settings to use when creating the data table
|
||||
*/
|
||||
export function createDataTable($dataTableElem: JQuery, settings: any): DataTables.DataTable {
|
||||
export function createDataTable($dataTableElem: JQuery, settings: DataTables.Settings): DataTables.DataTable {
|
||||
return $dataTableElem.DataTable(applyDefaultRendering(settings));
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ export function createDataTable($dataTableElem: JQuery, settings: any): DataTabl
|
||||
* @param{settings} The settings to check
|
||||
* @return The given settings with all columns having a rendering function
|
||||
*/
|
||||
//eslint-disable-next-line
|
||||
function applyDefaultRendering(settings: any): DataTables.SettingsLegacy {
|
||||
var tableColumns: DataTables.ColumnLegacy[] = null;
|
||||
let tableColumns: DataTables.ColumnLegacy[] = null;
|
||||
|
||||
if (settings.aoColumns) {
|
||||
tableColumns = settings.aoColumns;
|
||||
@@ -34,7 +35,7 @@ function applyDefaultRendering(settings: any): DataTables.SettingsLegacy {
|
||||
return settings;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tableColumns.length; i++) {
|
||||
for (let i = 0; i < tableColumns.length; i++) {
|
||||
// the column does not have a render function
|
||||
if (!tableColumns[i].mRender) {
|
||||
tableColumns[i].mRender = defaultDataRender;
|
||||
@@ -47,6 +48,7 @@ function applyDefaultRendering(settings: any): DataTables.SettingsLegacy {
|
||||
* Default data render function, whatever is done to data in here
|
||||
* will be done to any data which we do not specify a render for.
|
||||
*/
|
||||
function defaultDataRender(data: any, type: string, full: any) {
|
||||
//eslint-disable-next-line
|
||||
function defaultDataRender(data: any) {
|
||||
return Utilities.htmlEncode(data);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ describe("Documents tab", () => {
|
||||
describe("buildQuery", () => {
|
||||
it("should generate the right select query for SQL API", () => {
|
||||
const documentsTab = new DocumentsTab({
|
||||
partitionKey: undefined,
|
||||
partitionKey: null,
|
||||
documentIds: ko.observableArray<DocumentId>(),
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
@@ -82,9 +82,9 @@ describe("Documents tab", () => {
|
||||
container: mongoExplorer,
|
||||
});
|
||||
|
||||
it("should be false for undefined or undefined collection", () => {
|
||||
it("should be false for null or undefined collection", () => {
|
||||
const documentsTab = new DocumentsTab({
|
||||
partitionKey: undefined,
|
||||
partitionKey: null,
|
||||
documentIds: ko.observableArray<DocumentId>(),
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
@@ -94,10 +94,10 @@ describe("Documents tab", () => {
|
||||
expect(documentsTab.showPartitionKey).toBe(false);
|
||||
});
|
||||
|
||||
it("should be false for undefined or undefined partitionKey", () => {
|
||||
it("should be false for null or undefined partitionKey", () => {
|
||||
const documentsTab = new DocumentsTab({
|
||||
collection: collectionWithoutPartitionKey,
|
||||
partitionKey: undefined,
|
||||
partitionKey: null,
|
||||
documentIds: ko.observableArray<DocumentId>(),
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
@@ -110,7 +110,7 @@ describe("Documents tab", () => {
|
||||
it("should be true for non-Mongo accounts with system partitionKey", () => {
|
||||
const documentsTab = new DocumentsTab({
|
||||
collection: collectionWithSystemPartitionKey,
|
||||
partitionKey: undefined,
|
||||
partitionKey: null,
|
||||
documentIds: ko.observableArray<DocumentId>(),
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
@@ -126,7 +126,7 @@ describe("Documents tab", () => {
|
||||
});
|
||||
const documentsTab = new DocumentsTab({
|
||||
collection: mongoCollectionWithSystemPartitionKey,
|
||||
partitionKey: undefined,
|
||||
partitionKey: null,
|
||||
documentIds: ko.observableArray<DocumentId>(),
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
@@ -139,7 +139,7 @@ describe("Documents tab", () => {
|
||||
it("should be true for non-system partitionKey", () => {
|
||||
const documentsTab = new DocumentsTab({
|
||||
collection: collectionWithNonSystemPartitionKey,
|
||||
partitionKey: undefined,
|
||||
partitionKey: null,
|
||||
documentIds: ko.observableArray<DocumentId>(),
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as ko from "knockout";
|
||||
import * as Constants from "../Common/Constants";
|
||||
import * as ViewModels from "../Contracts/ViewModels";
|
||||
import * as Constants from "../Common/Constants";
|
||||
|
||||
export abstract class WaitsForTemplateViewModel implements ViewModels.WaitsForTemplate {
|
||||
public isTemplateReady: ko.Observable<boolean>;
|
||||
@@ -14,11 +14,11 @@ export abstract class WaitsForTemplateViewModel implements ViewModels.WaitsForTe
|
||||
callback(value);
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (e: KeyboardEvent) => {
|
||||
document.addEventListener("keydown", function (e: KeyboardEvent) {
|
||||
// To trap keyboard focus in AddCollection pane
|
||||
const firstFocusableElement = document.getElementById("closeBtnAddCollection");
|
||||
const lastFocusableElement = document.getElementById("submitBtnAddCollection");
|
||||
const isTabPressed = e.keyCode === Constants.KeyCodes.Tab;
|
||||
let firstFocusableElement = document.getElementById("closeBtnAddCollection");
|
||||
let lastFocusableElement = document.getElementById("submitBtnAddCollection");
|
||||
var isTabPressed = e.keyCode === Constants.KeyCodes.Tab;
|
||||
if (isTabPressed) {
|
||||
if (e.shiftKey) {
|
||||
/* shift + tab */ if (document.activeElement === firstFocusableElement) {
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { configContext } from "../../ConfigContext";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import * as DefaultExperienceUtility from "../../Shared/DefaultExperienceUtility";
|
||||
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
|
||||
import { userContext } from "../../UserContext";
|
||||
|
||||
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}`;
|
||||
};
|
||||
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;
|
||||
|
||||
export const generateEncryptedToken = async (readOnly = false): Promise<DataModels.GenerateTokenResponse> => {
|
||||
const url = configContext.BACKEND_ENDPOINT + "/api/tokens/generateToken" + _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);
|
||||
};
|
||||
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}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AccountKind, CapabilityNames } from "../../Common/Constants";
|
||||
import { AccessInputMetadata, ApiKind } from "../../Contracts/DataModels";
|
||||
import * as DefaultExperienceUtility from "../../Shared/DefaultExperienceUtility";
|
||||
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
|
||||
import { userContext } from "../../UserContext";
|
||||
|
||||
export function getDatabaseAccountPropertiesFromMetadata(metadata: AccessInputMetadata): unknown {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import * as DataModels from "../Contracts/DataModels";
|
||||
import { userContext } from "../UserContext";
|
||||
import * as DefaultExperienceUtility from "./DefaultExperienceUtility";
|
||||
import { DefaultExperienceUtility } from "./DefaultExperienceUtility";
|
||||
|
||||
describe("Default Experience Utility", () => {
|
||||
describe("getDefaultExperienceFromApiKind()", () => {
|
||||
const runScenario = (apiKind: number, expectedExperience: typeof userContext.apiType): void => {
|
||||
function runScenario(apiKind: number, expectedExperience: typeof userContext.apiType): void {
|
||||
const resolvedExperience = DefaultExperienceUtility.getDefaultExperienceFromApiKind(apiKind);
|
||||
expect(resolvedExperience).toEqual(expectedExperience);
|
||||
};
|
||||
}
|
||||
|
||||
describe("On SQL", () => {
|
||||
it("should return SQL", () => runScenario(DataModels.ApiKind.SQL, "SQL"));
|
||||
@@ -35,10 +35,10 @@ describe("Default Experience Utility", () => {
|
||||
});
|
||||
|
||||
describe("getApiKindFromDefaultExperience()", () => {
|
||||
const runScenario = (defaultExperience: typeof userContext.apiType | null, expectedApiKind: number): void => {
|
||||
function runScenario(defaultExperience: typeof userContext.apiType | null, expectedApiKind: number): void {
|
||||
const resolvedApiKind = DefaultExperienceUtility.getApiKindFromDefaultExperience(defaultExperience);
|
||||
expect(resolvedApiKind).toEqual(expectedApiKind);
|
||||
};
|
||||
}
|
||||
|
||||
describe("On SQL", () => {
|
||||
it("should return SQL", () => runScenario("SQL", DataModels.ApiKind.SQL));
|
||||
@@ -60,8 +60,8 @@ describe("Default Experience Utility", () => {
|
||||
it("should return Graph", () => runScenario("Gremlin", DataModels.ApiKind.Graph));
|
||||
});
|
||||
|
||||
describe("On undefined", () => {
|
||||
it("should return SQL", () => runScenario(undefined, DataModels.ApiKind.SQL));
|
||||
describe("On null", () => {
|
||||
it("should return SQL", () => runScenario(null, DataModels.ApiKind.SQL));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,45 +1,47 @@
|
||||
import * as DataModels from "../Contracts/DataModels";
|
||||
import { userContext } from "../UserContext";
|
||||
|
||||
export const getApiKindFromDefaultExperience = (defaultExperience: typeof userContext.apiType): DataModels.ApiKind => {
|
||||
if (!defaultExperience) {
|
||||
return DataModels.ApiKind.SQL;
|
||||
}
|
||||
|
||||
switch (defaultExperience) {
|
||||
case "SQL":
|
||||
export class DefaultExperienceUtility {
|
||||
public static getApiKindFromDefaultExperience(defaultExperience: typeof userContext.apiType): DataModels.ApiKind {
|
||||
if (!defaultExperience) {
|
||||
return DataModels.ApiKind.SQL;
|
||||
case "Mongo":
|
||||
return DataModels.ApiKind.MongoDB;
|
||||
case "Tables":
|
||||
return DataModels.ApiKind.Table;
|
||||
case "Cassandra":
|
||||
return DataModels.ApiKind.Cassandra;
|
||||
case "Gremlin":
|
||||
return DataModels.ApiKind.Graph;
|
||||
default:
|
||||
return DataModels.ApiKind.SQL;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const getDefaultExperienceFromApiKind = (apiKind: DataModels.ApiKind): typeof userContext.apiType => {
|
||||
if (apiKind === undefined) {
|
||||
return "SQL";
|
||||
switch (defaultExperience) {
|
||||
case "SQL":
|
||||
return DataModels.ApiKind.SQL;
|
||||
case "Mongo":
|
||||
return DataModels.ApiKind.MongoDB;
|
||||
case "Tables":
|
||||
return DataModels.ApiKind.Table;
|
||||
case "Cassandra":
|
||||
return DataModels.ApiKind.Cassandra;
|
||||
case "Gremlin":
|
||||
return DataModels.ApiKind.Graph;
|
||||
default:
|
||||
return DataModels.ApiKind.SQL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (apiKind) {
|
||||
case DataModels.ApiKind.SQL:
|
||||
return "SQL";
|
||||
case DataModels.ApiKind.MongoDB:
|
||||
case DataModels.ApiKind.MongoDBCompute:
|
||||
return "Mongo";
|
||||
case DataModels.ApiKind.Table:
|
||||
return "Tables";
|
||||
case DataModels.ApiKind.Cassandra:
|
||||
return "Cassandra";
|
||||
case DataModels.ApiKind.Graph:
|
||||
return "Gremlin";
|
||||
default:
|
||||
public static getDefaultExperienceFromApiKind(apiKind: DataModels.ApiKind): typeof userContext.apiType {
|
||||
if (apiKind == null) {
|
||||
return "SQL";
|
||||
}
|
||||
|
||||
switch (apiKind) {
|
||||
case DataModels.ApiKind.SQL:
|
||||
return "SQL";
|
||||
case DataModels.ApiKind.MongoDB:
|
||||
case DataModels.ApiKind.MongoDBCompute:
|
||||
return "Mongo";
|
||||
case DataModels.ApiKind.Table:
|
||||
return "Tables";
|
||||
case DataModels.ApiKind.Cassandra:
|
||||
return "Cassandra";
|
||||
case DataModels.ApiKind.Graph:
|
||||
return "Gremlin";
|
||||
default:
|
||||
return "SQL";
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,35 +5,37 @@ import { ServerConnection, TerminalManager } from "@jupyterlab/services";
|
||||
import { Terminal } from "@jupyterlab/terminal";
|
||||
import { Panel, Widget } from "@phosphor/widgets";
|
||||
|
||||
export const createTerminalApp = async (serverSettings: ServerConnection.ISettings) => {
|
||||
const manager = new TerminalManager({
|
||||
serverSettings: serverSettings,
|
||||
});
|
||||
const session = await manager.startNew();
|
||||
const term = new Terminal(session, { theme: "dark", shutdownOnClose: true });
|
||||
export class JupyterLabAppFactory {
|
||||
public static async createTerminalApp(serverSettings: ServerConnection.ISettings) {
|
||||
const manager = new TerminalManager({
|
||||
serverSettings: serverSettings,
|
||||
});
|
||||
const session = await manager.startNew();
|
||||
const term = new Terminal(session, { theme: "dark", shutdownOnClose: true });
|
||||
|
||||
if (!term) {
|
||||
console.error("Failed starting terminal");
|
||||
return;
|
||||
if (!term) {
|
||||
console.error("Failed starting terminal");
|
||||
return;
|
||||
}
|
||||
|
||||
term.title.closable = false;
|
||||
term.addClass("terminalWidget");
|
||||
|
||||
let panel = new Panel();
|
||||
panel.addWidget(term as any);
|
||||
panel.id = "main";
|
||||
|
||||
// Attach the widget to the dom.
|
||||
Widget.attach(panel, document.body);
|
||||
|
||||
// Handle resize events.
|
||||
window.addEventListener("resize", () => {
|
||||
panel.update();
|
||||
});
|
||||
|
||||
// Dispose terminal when unloading.
|
||||
window.addEventListener("unload", () => {
|
||||
panel.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
term.title.closable = false;
|
||||
term.addClass("terminalWidget");
|
||||
|
||||
const panel = new Panel();
|
||||
panel.addWidget(term as any);
|
||||
panel.id = "main";
|
||||
|
||||
// Attach the widget to the dom.
|
||||
Widget.attach(panel, document.body);
|
||||
|
||||
// Handle resize events.
|
||||
window.addEventListener("resize", () => {
|
||||
panel.update();
|
||||
});
|
||||
|
||||
// Dispose terminal when unloading.
|
||||
window.addEventListener("unload", () => {
|
||||
panel.dispose();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Action } from "../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
|
||||
import { updateUserContext } from "../UserContext";
|
||||
import "./index.css";
|
||||
import { createTerminalApp } from "./JupyterLabAppFactory";
|
||||
import { JupyterLabAppFactory } from "./JupyterLabAppFactory";
|
||||
import { TerminalProps } from "./TerminalProps";
|
||||
|
||||
const createServerSettings = (props: TerminalProps): ServerConnection.ISettings => {
|
||||
@@ -54,7 +54,7 @@ const initTerminal = async (props: TerminalProps) => {
|
||||
const startTime = TelemetryProcessor.traceStart(Action.OpenTerminal, data);
|
||||
|
||||
try {
|
||||
await createTerminalApp(serverSettings);
|
||||
await JupyterLabAppFactory.createTerminalApp(serverSettings);
|
||||
TelemetryProcessor.traceSuccess(Action.OpenTerminal, data, startTime);
|
||||
} catch (error) {
|
||||
TelemetryProcessor.traceFailure(Action.OpenTerminal, data, startTime);
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
getDatabaseAccountPropertiesFromMetadata,
|
||||
} from "../Platform/Hosted/HostedUtils";
|
||||
import { CollectionCreation } from "../Shared/Constants";
|
||||
import * as DefaultExperienceUtility from "../Shared/DefaultExperienceUtility";
|
||||
import { DefaultExperienceUtility } from "../Shared/DefaultExperienceUtility";
|
||||
import { PortalEnv, updateUserContext, userContext } from "../UserContext";
|
||||
import { listKeys } from "../Utils/arm/generatedClients/cosmos/databaseAccounts";
|
||||
import { DatabaseAccountListKeysResult } from "../Utils/arm/generatedClients/cosmos/types";
|
||||
|
||||
Reference in New Issue
Block a user