mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-03-27 12:10:09 +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",
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
"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": {
|
"aws-sign2": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
"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": {
|
"file-uri-to-path": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
"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": {
|
"react-error-overlay": {
|
||||||
"version": "6.0.9",
|
"version": "6.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
"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": "14.0.2",
|
||||||
"react-dnd-html5-backend": "14.0.0",
|
"react-dnd-html5-backend": "14.0.0",
|
||||||
"react-dom": "16.13.1",
|
"react-dom": "16.13.1",
|
||||||
|
"react-dropzone": "12.0.4",
|
||||||
"react-hotkeys": "2.0.0",
|
"react-hotkeys": "2.0.0",
|
||||||
"react-i18next": "11.8.5",
|
"react-i18next": "11.8.5",
|
||||||
"react-notification-system": "0.2.17",
|
"react-notification-system": "0.2.17",
|
||||||
|
@ -9,6 +9,7 @@ export enum TabKind {
|
|||||||
Graph,
|
Graph,
|
||||||
SQLQuery,
|
SQLQuery,
|
||||||
ScaleSettings,
|
ScaleSettings,
|
||||||
|
DataUploader,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,6 +142,7 @@ export interface Collection extends CollectionBase {
|
|||||||
onGraphDocumentsClick(): void;
|
onGraphDocumentsClick(): void;
|
||||||
onMongoDBDocumentsClick(): void;
|
onMongoDBDocumentsClick(): void;
|
||||||
onSchemaAnalyzerClick(): void;
|
onSchemaAnalyzerClick(): void;
|
||||||
|
onDataUploaderClick(): void;
|
||||||
openTab(): void;
|
openTab(): void;
|
||||||
|
|
||||||
onSettingsClick: () => Promise<void>;
|
onSettingsClick: () => Promise<void>;
|
||||||
@ -364,6 +365,7 @@ export enum CollectionTabKind {
|
|||||||
CollectionSettingsV2 = 20,
|
CollectionSettingsV2 = 20,
|
||||||
DatabaseSettingsV2 = 21,
|
DatabaseSettingsV2 = 21,
|
||||||
SchemaAnalyzer = 22,
|
SchemaAnalyzer = 22,
|
||||||
|
DataUploader = 23,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TerminalKind {
|
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 { ImmutableNotebook } from "@nteract/commutable";
|
||||||
import type { IContentProvider } from "@nteract/core";
|
import type { IContentProvider } from "@nteract/core";
|
||||||
|
import { DataUploaderNotebook } from "Explorer/Notebook/DataUploader/DataUploaderUtils";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { contents } from "rx-jupyter";
|
import { contents } from "rx-jupyter";
|
||||||
import { Areas, HttpStatusCodes } from "../../Common/Constants";
|
import { Areas, HttpStatusCodes } from "../../Common/Constants";
|
||||||
@ -68,6 +69,10 @@ export default class NotebookManager {
|
|||||||
readonly: true,
|
readonly: true,
|
||||||
content: SchemaAnalyzerNotebook,
|
content: SchemaAnalyzerNotebook,
|
||||||
},
|
},
|
||||||
|
[DataUploaderNotebook.path]: {
|
||||||
|
readonly: true,
|
||||||
|
content: DataUploaderNotebook,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.gitHubContentProvider = new GitHubContentProvider({
|
this.gitHubContentProvider = new GitHubContentProvider({
|
||||||
|
@ -26,6 +26,7 @@ describe("OpenActions", () => {
|
|||||||
collection.onDocumentDBDocumentsClick = jest.fn();
|
collection.onDocumentDBDocumentsClick = jest.fn();
|
||||||
collection.onMongoDBDocumentsClick = jest.fn();
|
collection.onMongoDBDocumentsClick = jest.fn();
|
||||||
collection.onSchemaAnalyzerClick = jest.fn();
|
collection.onSchemaAnalyzerClick = jest.fn();
|
||||||
|
collection.onDataUploaderClick = jest.fn();
|
||||||
collection.onTableEntitiesClick = jest.fn();
|
collection.onTableEntitiesClick = jest.fn();
|
||||||
collection.onGraphDocumentsClick = jest.fn();
|
collection.onGraphDocumentsClick = jest.fn();
|
||||||
collection.onNewQueryClick = jest.fn();
|
collection.onNewQueryClick = jest.fn();
|
||||||
|
@ -86,6 +86,14 @@ function openCollectionTab(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
action.tabKind === ActionContracts.TabKind.DataUploader ||
|
||||||
|
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.DataUploader]
|
||||||
|
) {
|
||||||
|
collection.onDataUploaderClick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
action.tabKind === ActionContracts.TabKind.TableEntities ||
|
action.tabKind === ActionContracts.TabKind.TableEntities ||
|
||||||
action.tabKind === ActionContracts.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> => {
|
public onSettingsClick = async (): Promise<void> => {
|
||||||
useSelectedNode.getState().setSelectedNode(this);
|
useSelectedNode.getState().setSelectedNode(this);
|
||||||
const throughputCap = userContext.databaseAccount?.properties.capacity?.totalThroughputLimit;
|
const throughputCap = userContext.databaseAccount?.properties.capacity?.totalThroughputLimit;
|
||||||
|
@ -526,6 +526,15 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
|
|||||||
.getState()
|
.getState()
|
||||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.SchemaAnalyzer]),
|
.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()) {
|
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
||||||
|
@ -283,6 +283,15 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
|||||||
.getState()
|
.getState()
|
||||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.SchemaAnalyzer]),
|
.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()) {
|
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user