mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-03-14 05:45:03 +00:00
Initial implementation of dropzone component
This commit is contained in:
parent
5c8016ecd6
commit
4cc98f0b62
42
package-lock.json
generated
42
package-lock.json
generated
@ -6866,6 +6866,11 @@
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||
},
|
||||
"attr-accept": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
|
||||
"integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg=="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
@ -10815,6 +10820,21 @@
|
||||
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
||||
},
|
||||
"file-selector": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz",
|
||||
"integrity": "sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg==",
|
||||
"requires": {
|
||||
"tslib": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
@ -20978,6 +20998,28 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-dropzone": {
|
||||
"version": "12.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-12.0.4.tgz",
|
||||
"integrity": "sha512-fcqHEYe1MzAghU6/Hz86lHDlBNsA+lO48nAcm7/wA+kIzwS6uuJbUG33tBZjksj7GAZ1iUQ6NHwjUURPmSGang==",
|
||||
"requires": {
|
||||
"attr-accept": "^2.2.2",
|
||||
"file-selector": "^0.4.0",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-error-overlay": {
|
||||
"version": "6.0.9",
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
||||
|
@ -86,6 +86,7 @@
|
||||
"react-dnd": "14.0.2",
|
||||
"react-dnd-html5-backend": "14.0.0",
|
||||
"react-dom": "16.13.1",
|
||||
"react-dropzone": "12.0.4",
|
||||
"react-hotkeys": "2.0.0",
|
||||
"react-i18next": "11.8.5",
|
||||
"react-notification-system": "0.2.17",
|
||||
|
@ -9,6 +9,7 @@ export enum TabKind {
|
||||
Graph,
|
||||
SQLQuery,
|
||||
ScaleSettings,
|
||||
DataUploader,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,6 +142,7 @@ export interface Collection extends CollectionBase {
|
||||
onGraphDocumentsClick(): void;
|
||||
onMongoDBDocumentsClick(): void;
|
||||
onSchemaAnalyzerClick(): void;
|
||||
onDataUploaderClick(): void;
|
||||
openTab(): void;
|
||||
|
||||
onSettingsClick: () => Promise<void>;
|
||||
@ -364,6 +365,7 @@ export enum CollectionTabKind {
|
||||
CollectionSettingsV2 = 20,
|
||||
DatabaseSettingsV2 = 21,
|
||||
SchemaAnalyzer = 22,
|
||||
DataUploader = 23,
|
||||
}
|
||||
|
||||
export enum TerminalKind {
|
||||
|
5
src/Explorer/Notebook/DataUploader/DataUploader.less
Normal file
5
src/Explorer/Notebook/DataUploader/DataUploader.less
Normal file
@ -0,0 +1,5 @@
|
||||
.dataUploader {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
209
src/Explorer/Notebook/DataUploader/DataUploader.tsx
Normal file
209
src/Explorer/Notebook/DataUploader/DataUploader.tsx
Normal file
@ -0,0 +1,209 @@
|
||||
import { ImmutableOutput } from "@nteract/commutable";
|
||||
import { actions, AppState, ContentRef, KernelRef, selectors } from "@nteract/core";
|
||||
import Immutable from "immutable";
|
||||
import React, { CSSProperties, useCallback, useMemo } from "react";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { connect } from "react-redux";
|
||||
import { Dispatch } from "redux";
|
||||
import "./DataUploader.less";
|
||||
|
||||
interface DataUploaderPureProps {
|
||||
contentRef: ContentRef;
|
||||
kernelRef: KernelRef;
|
||||
databaseId: string;
|
||||
collectionId: string;
|
||||
}
|
||||
|
||||
const getColor = (props) => {
|
||||
if (props.isDragAccept) {
|
||||
return "#00e676";
|
||||
}
|
||||
if (props.isDragReject) {
|
||||
return "#ff1744";
|
||||
}
|
||||
if (props.isFocused) {
|
||||
return "#2196f3";
|
||||
}
|
||||
return "#eeeeee";
|
||||
};
|
||||
|
||||
interface DataUploaderDispatchProps {
|
||||
runCell: (contentRef: ContentRef, cellId: string) => void;
|
||||
addTransform: (transform: React.ComponentType & { MIMETYPE: string }) => void;
|
||||
updateCell: (text: string, id: string, contentRef: ContentRef) => void;
|
||||
}
|
||||
|
||||
type DataUploaderProps = DataUploaderPureProps & StateProps & DataUploaderDispatchProps;
|
||||
|
||||
const DataUploader: React.FC<DataUploaderProps> = (props) => {
|
||||
// componentDidMount(): void {
|
||||
// loadTransform(this.props);
|
||||
// }
|
||||
|
||||
// private onAnalyzeButtonClick = (filter: string = DefaultFilter, sampleSize: string = this.state.sampleSize) => {
|
||||
// const query = {
|
||||
// command: "listSchema",
|
||||
// database: this.props.databaseId,
|
||||
// collection: this.props.collectionId,
|
||||
// outputType: this.state.outputType,
|
||||
// filter,
|
||||
// sampleSize,
|
||||
// };
|
||||
|
||||
// this.setState({
|
||||
// isFiltering: true,
|
||||
// });
|
||||
|
||||
// this.props.updateCell(JSON.stringify(query), this.props.firstCellId, this.props.contentRef);
|
||||
|
||||
// this.clickAnalyzeTelemetryStartKey = traceStart(Action.DataUploaderClickAnalyze, {
|
||||
// database: this.props.databaseId,
|
||||
// collection: this.props.collectionId,
|
||||
// sampleSize,
|
||||
// });
|
||||
|
||||
// this.props.runCell(this.props.contentRef, this.props.firstCellId);
|
||||
// };
|
||||
|
||||
const { firstCellId: id, contentRef, kernelStatus } = props;
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("firstCellId: id, contentRef, kernelStatus", id, contentRef, kernelStatus);
|
||||
|
||||
const isKernelBusy = kernelStatus === "busy";
|
||||
const isKernelIdle = kernelStatus === "idle";
|
||||
|
||||
const baseStyle: CSSProperties = {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
padding: "20px",
|
||||
borderWidth: 2,
|
||||
borderRadius: 2,
|
||||
borderColor: "#eeeeee",
|
||||
borderStyle: "dashed",
|
||||
backgroundColor: "#fafafa",
|
||||
color: "#bdbdbd",
|
||||
transition: "border .3s ease-in-out",
|
||||
};
|
||||
|
||||
const activeStyle = {
|
||||
borderColor: "#2196f3",
|
||||
};
|
||||
|
||||
const acceptStyle = {
|
||||
borderColor: "#00e676",
|
||||
};
|
||||
|
||||
const rejectStyle = {
|
||||
borderColor: "#ff1744",
|
||||
};
|
||||
|
||||
const onDrop = useCallback((acceptedFiles) => {
|
||||
//eslint-disable-next-line no-console
|
||||
console.log("acceptedFiles", acceptedFiles);
|
||||
}, []);
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({
|
||||
onDrop,
|
||||
accept: ".json",
|
||||
});
|
||||
|
||||
const style = useMemo(
|
||||
() => ({
|
||||
...baseStyle,
|
||||
...(isDragActive ? activeStyle : {}),
|
||||
...(isDragAccept ? acceptStyle : {}),
|
||||
...(isDragReject ? rejectStyle : {}),
|
||||
}),
|
||||
[isDragActive, isDragReject, isDragAccept]
|
||||
);
|
||||
|
||||
if (!id) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...getRootProps({ style })}>
|
||||
<input {...getInputProps()} />
|
||||
<div>Drag and drop your json file here</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface StateProps {
|
||||
firstCellId: string;
|
||||
kernelStatus: string;
|
||||
outputs: Immutable.List<ImmutableOutput>;
|
||||
}
|
||||
|
||||
interface InitialProps {
|
||||
kernelRef: string;
|
||||
contentRef: string;
|
||||
}
|
||||
|
||||
// Redux
|
||||
const makeMapStateToProps = (state: AppState, initialProps: InitialProps) => {
|
||||
const { kernelRef, contentRef } = initialProps;
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
let kernelStatus;
|
||||
let firstCellId;
|
||||
let outputs;
|
||||
|
||||
const kernel = selectors.kernel(state, { kernelRef });
|
||||
if (kernel) {
|
||||
kernelStatus = kernel.status;
|
||||
}
|
||||
|
||||
const content = selectors.content(state, { contentRef });
|
||||
if (content?.type === "notebook") {
|
||||
const cellOrder = selectors.notebook.cellOrder(content.model);
|
||||
if (cellOrder.size > 0) {
|
||||
firstCellId = cellOrder.first() as string;
|
||||
|
||||
const model = selectors.model(state, { contentRef });
|
||||
if (model && model.type === "notebook") {
|
||||
const cell = selectors.notebook.cellById(model, { id: firstCellId });
|
||||
if (cell) {
|
||||
outputs = cell.get("outputs", Immutable.List());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
firstCellId,
|
||||
kernelStatus,
|
||||
outputs,
|
||||
};
|
||||
};
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const makeMapDispatchToProps = () => {
|
||||
const mapDispatchToProps = (dispatch: Dispatch) => {
|
||||
return {
|
||||
addTransform: (transform: React.ComponentType & { MIMETYPE: string }) => {
|
||||
return dispatch(
|
||||
actions.addTransform({
|
||||
mediaType: transform.MIMETYPE,
|
||||
component: transform,
|
||||
})
|
||||
);
|
||||
},
|
||||
runCell: (contentRef: ContentRef, cellId: string) => {
|
||||
return dispatch(
|
||||
actions.executeCell({
|
||||
contentRef,
|
||||
id: cellId,
|
||||
})
|
||||
);
|
||||
},
|
||||
updateCell: (text: string, id: string, contentRef: ContentRef) => {
|
||||
dispatch(actions.updateCellSource({ id, contentRef, value: text }));
|
||||
},
|
||||
};
|
||||
};
|
||||
return mapDispatchToProps;
|
||||
};
|
||||
|
||||
export default connect(makeMapStateToProps, makeMapDispatchToProps)(DataUploader);
|
48
src/Explorer/Notebook/DataUploader/DataUploaderAdapter.tsx
Normal file
48
src/Explorer/Notebook/DataUploader/DataUploaderAdapter.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
import { actions, createContentRef, createKernelRef, KernelRef } from "@nteract/core";
|
||||
import DataUploader from "Explorer/Notebook/DataUploader/DataUploader";
|
||||
import * as React from "react";
|
||||
import { Provider } from "react-redux";
|
||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||
import {
|
||||
NotebookComponentBootstrapper,
|
||||
NotebookComponentBootstrapperOptions,
|
||||
} from "../NotebookComponent/NotebookComponentBootstrapper";
|
||||
import { DataUploaderNotebook } from "./DataUploaderUtils";
|
||||
|
||||
export class DataUploaderAdapter extends NotebookComponentBootstrapper implements ReactAdapter {
|
||||
public parameters: unknown;
|
||||
private kernelRef: KernelRef;
|
||||
|
||||
constructor(options: NotebookComponentBootstrapperOptions, private databaseId: string, private collectionId: string) {
|
||||
super(options);
|
||||
|
||||
if (!this.contentRef) {
|
||||
this.contentRef = createContentRef();
|
||||
this.kernelRef = createKernelRef();
|
||||
|
||||
this.getStore().dispatch(
|
||||
actions.fetchContent({
|
||||
filepath: DataUploaderNotebook.path,
|
||||
params: {},
|
||||
kernelRef: this.kernelRef,
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public renderComponent(): JSX.Element {
|
||||
const props = {
|
||||
contentRef: this.contentRef,
|
||||
kernelRef: this.kernelRef,
|
||||
databaseId: this.databaseId,
|
||||
collectionId: this.collectionId,
|
||||
};
|
||||
|
||||
return (
|
||||
<Provider store={this.getStore()}>
|
||||
<DataUploader {...props} />;
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
}
|
44
src/Explorer/Notebook/DataUploader/DataUploaderUtils.ts
Normal file
44
src/Explorer/Notebook/DataUploader/DataUploaderUtils.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Notebook } from "@nteract/commutable";
|
||||
import { IContent } from "@nteract/types";
|
||||
import * as InMemoryContentProviderUtils from "../NotebookComponent/ContentProviders/InMemoryContentProviderUtils";
|
||||
|
||||
const notebookName = "data-uploader-component-notebook.ipynb";
|
||||
const notebookPath = InMemoryContentProviderUtils.toContentUri(notebookName);
|
||||
const notebook: Notebook = {
|
||||
cells: [
|
||||
{
|
||||
cell_type: "code",
|
||||
metadata: {},
|
||||
execution_count: 0,
|
||||
outputs: [],
|
||||
source: "",
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
kernelspec: {
|
||||
displayName: "Mongo",
|
||||
language: "mongocli",
|
||||
name: "mongo",
|
||||
},
|
||||
language_info: {
|
||||
file_extension: "ipynb",
|
||||
mimetype: "application/json",
|
||||
name: "mongo",
|
||||
version: "1.0",
|
||||
},
|
||||
},
|
||||
nbformat: 4,
|
||||
nbformat_minor: 4,
|
||||
};
|
||||
|
||||
export const DataUploaderNotebook: IContent<"notebook"> = {
|
||||
name: notebookName,
|
||||
path: notebookPath,
|
||||
type: "notebook",
|
||||
writable: true,
|
||||
created: "",
|
||||
last_modified: "",
|
||||
mimetype: "application/x-ipynb+json",
|
||||
content: notebook,
|
||||
format: "json",
|
||||
};
|
@ -4,6 +4,7 @@
|
||||
|
||||
import { ImmutableNotebook } from "@nteract/commutable";
|
||||
import type { IContentProvider } from "@nteract/core";
|
||||
import { DataUploaderNotebook } from "Explorer/Notebook/DataUploader/DataUploaderUtils";
|
||||
import React from "react";
|
||||
import { contents } from "rx-jupyter";
|
||||
import { Areas, HttpStatusCodes } from "../../Common/Constants";
|
||||
@ -68,6 +69,10 @@ export default class NotebookManager {
|
||||
readonly: true,
|
||||
content: SchemaAnalyzerNotebook,
|
||||
},
|
||||
[DataUploaderNotebook.path]: {
|
||||
readonly: true,
|
||||
content: DataUploaderNotebook,
|
||||
},
|
||||
});
|
||||
|
||||
this.gitHubContentProvider = new GitHubContentProvider({
|
||||
|
@ -26,6 +26,7 @@ describe("OpenActions", () => {
|
||||
collection.onDocumentDBDocumentsClick = jest.fn();
|
||||
collection.onMongoDBDocumentsClick = jest.fn();
|
||||
collection.onSchemaAnalyzerClick = jest.fn();
|
||||
collection.onDataUploaderClick = jest.fn();
|
||||
collection.onTableEntitiesClick = jest.fn();
|
||||
collection.onGraphDocumentsClick = jest.fn();
|
||||
collection.onNewQueryClick = jest.fn();
|
||||
|
@ -86,6 +86,14 @@ function openCollectionTab(
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
action.tabKind === ActionContracts.TabKind.DataUploader ||
|
||||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.DataUploader]
|
||||
) {
|
||||
collection.onDataUploaderClick();
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
action.tabKind === ActionContracts.TabKind.TableEntities ||
|
||||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.TableEntities]
|
||||
|
41
src/Explorer/Tabs/DataUploaderTab.ts
Normal file
41
src/Explorer/Tabs/DataUploaderTab.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import { traceSuccess } from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { DataUploaderAdapter } from "../Notebook/DataUploader/DataUploaderAdapter";
|
||||
import NotebookTabBase, { NotebookTabBaseOptions } from "./NotebookTabBase";
|
||||
|
||||
export default class DataUploaderTab extends NotebookTabBase {
|
||||
public readonly html = '<div data-bind="react:DataUploaderAdapter" style="height: 100%"></div>';
|
||||
private DataUploaderAdapter: DataUploaderAdapter;
|
||||
|
||||
constructor(options: NotebookTabBaseOptions) {
|
||||
super(options);
|
||||
this.DataUploaderAdapter = new DataUploaderAdapter(
|
||||
{
|
||||
contentRef: undefined,
|
||||
notebookClient: NotebookTabBase.clientManager,
|
||||
},
|
||||
options.collection?.databaseId,
|
||||
options.collection?.id()
|
||||
);
|
||||
}
|
||||
|
||||
public onActivate(): void {
|
||||
traceSuccess(
|
||||
Action.Tab,
|
||||
{
|
||||
databaseName: this.collection?.databaseId,
|
||||
collectionName: this.collection?.id,
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: "Upload",
|
||||
},
|
||||
this.onLoadStartKey
|
||||
);
|
||||
|
||||
super.onActivate();
|
||||
}
|
||||
|
||||
protected buildCommandBarOptions(): void {
|
||||
this.updateNavbarWithTabsButtons();
|
||||
}
|
||||
}
|
@ -574,6 +574,52 @@ export default class Collection implements ViewModels.Collection {
|
||||
);
|
||||
};
|
||||
|
||||
public onDataUploaderClick = async () => {
|
||||
if (useNotebook.getState().isPhoenixFeatures) {
|
||||
await this.container.allocateContainer();
|
||||
}
|
||||
useSelectedNode.getState().setSelectedNode(this);
|
||||
this.selectedSubnodeKind(ViewModels.CollectionTabKind.SchemaAnalyzer);
|
||||
const DataUploaderTab = await (await import("../Tabs/DataUploaderTab")).default;
|
||||
TelemetryProcessor.trace(Action.SelectItem, ActionModifiers.Mark, {
|
||||
description: "Data uploader node",
|
||||
databaseName: this.databaseId,
|
||||
collectionName: this.id(),
|
||||
dataExplorerArea: Constants.Areas.ResourceTree,
|
||||
});
|
||||
|
||||
for (const tab of useTabs.getState().openedTabs) {
|
||||
if (
|
||||
tab instanceof DataUploaderTab &&
|
||||
tab.collection?.databaseId === this.databaseId &&
|
||||
tab.collection?.id() === this.id()
|
||||
) {
|
||||
return useTabs.getState().activateTab(tab);
|
||||
}
|
||||
}
|
||||
|
||||
const startKey = TelemetryProcessor.traceStart(Action.Tab, {
|
||||
databaseName: this.databaseId,
|
||||
collectionName: this.id(),
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: "Upload",
|
||||
});
|
||||
this.documentIds([]);
|
||||
useTabs.getState().activateNewTab(
|
||||
new DataUploaderTab({
|
||||
account: userContext.databaseAccount,
|
||||
masterKey: userContext.masterKey || "",
|
||||
container: this.container,
|
||||
tabKind: ViewModels.CollectionTabKind.DataUploader,
|
||||
title: "Upload",
|
||||
tabPath: "",
|
||||
collection: this,
|
||||
node: this,
|
||||
onLoadStartKey: startKey,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
public onSettingsClick = async (): Promise<void> => {
|
||||
useSelectedNode.getState().setSelectedNode(this);
|
||||
const throughputCap = userContext.databaseAccount?.properties.capacity?.totalThroughputLimit;
|
||||
|
@ -526,6 +526,15 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
|
||||
.getState()
|
||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.SchemaAnalyzer]),
|
||||
});
|
||||
|
||||
children.push({
|
||||
label: "Data Upload (Preview)",
|
||||
onClick: collection.onDataUploaderClick.bind(collection),
|
||||
isSelected: () =>
|
||||
useSelectedNode
|
||||
.getState()
|
||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.DataUploader]),
|
||||
});
|
||||
}
|
||||
|
||||
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
||||
|
@ -283,6 +283,15 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
||||
.getState()
|
||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.SchemaAnalyzer]),
|
||||
});
|
||||
|
||||
children.push({
|
||||
label: "Data Upload (Preview)",
|
||||
onClick: collection.onDataUploaderClick.bind(collection),
|
||||
isSelected: () =>
|
||||
useSelectedNode
|
||||
.getState()
|
||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.DataUploader]),
|
||||
});
|
||||
}
|
||||
|
||||
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user