mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +00:00
Prettier 2.0 (#393)
This commit is contained in:
@@ -23,7 +23,7 @@ import {
|
||||
HostRecord,
|
||||
HostRef,
|
||||
KernelspecsRef,
|
||||
IContentProvider
|
||||
IContentProvider,
|
||||
} from "@nteract/core";
|
||||
import { Media } from "@nteract/outputs";
|
||||
import TransformVDOM from "@nteract/transform-vdom";
|
||||
@@ -73,7 +73,7 @@ export class NotebookClientV2 {
|
||||
this.getStore().dispatch(
|
||||
actions.fetchKernelspecs({
|
||||
hostRef: this.contentHostRef,
|
||||
kernelspecsRef: this.kernelSpecsRef
|
||||
kernelspecsRef: this.kernelSpecsRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ export class NotebookClientV2 {
|
||||
basePath: "/", // Jupyter server base URL
|
||||
bookstoreEnabled: false, //!!config.bookstore.version,
|
||||
showHeaderEditor: true,
|
||||
crossDomain: true
|
||||
crossDomain: true,
|
||||
});
|
||||
|
||||
this.contentHostRef = createHostRef();
|
||||
@@ -111,7 +111,7 @@ export class NotebookClientV2 {
|
||||
const initialState: CdbAppState = {
|
||||
app: makeAppRecord({
|
||||
version: "dataExplorer 1.0",
|
||||
host: jupyterHostRecord
|
||||
host: jupyterHostRecord,
|
||||
// TODO: tamitta: notificationSystem.addNotification was removed, do we need a substitute?
|
||||
}),
|
||||
core: makeStateRecord({
|
||||
@@ -119,11 +119,11 @@ export class NotebookClientV2 {
|
||||
entities: makeEntitiesRecord({
|
||||
editors: makeEditorsRecord({}),
|
||||
hosts: makeHostsRecord({
|
||||
byRef: Immutable.Map<string, HostRecord>().set(this.contentHostRef, jupyterHostRecord)
|
||||
byRef: Immutable.Map<string, HostRecord>().set(this.contentHostRef, jupyterHostRecord),
|
||||
}),
|
||||
comms: makeCommsRecord(),
|
||||
contents: makeContentsRecord({
|
||||
byRef: Immutable.Map<string, ContentRecord>()
|
||||
byRef: Immutable.Map<string, ContentRecord>(),
|
||||
}),
|
||||
transforms: makeTransformsRecord({
|
||||
displayOrder: Immutable.List([
|
||||
@@ -150,7 +150,7 @@ export class NotebookClientV2 {
|
||||
"image/gif",
|
||||
"image/png",
|
||||
"image/jpeg",
|
||||
"text/plain"
|
||||
"text/plain",
|
||||
]),
|
||||
byId: Immutable.Map({
|
||||
"text/vnd.plotly.v1+html": NullTransform,
|
||||
@@ -176,15 +176,15 @@ export class NotebookClientV2 {
|
||||
"image/gif": Media.Image,
|
||||
"image/png": Media.Image,
|
||||
"image/jpeg": Media.Image,
|
||||
"text/plain": Media.Plain
|
||||
})
|
||||
})
|
||||
})
|
||||
"text/plain": Media.Plain,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
cdb: makeCdbRecord({
|
||||
databaseAccountName: params.databaseAccountName,
|
||||
defaultExperience: params.defaultExperience
|
||||
})
|
||||
defaultExperience: params.defaultExperience,
|
||||
}),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -194,16 +194,16 @@ export class NotebookClientV2 {
|
||||
*/
|
||||
const cacheKernelSpecsMiddleware: Middleware = <D extends Dispatch<AnyAction>, S extends AppState>({
|
||||
dispatch,
|
||||
getState
|
||||
getState,
|
||||
}: MiddlewareAPI<D, S>) => (next: Dispatch<AnyAction>) => <A extends AnyAction>(action: A): A => {
|
||||
switch (action.type) {
|
||||
case actions.FETCH_KERNELSPECS_FULFILLED: {
|
||||
const payload = ((action as unknown) as actions.FetchKernelspecsFulfilled).payload;
|
||||
const defaultKernelName = payload.defaultKernelName;
|
||||
this.kernelSpecsForDisplay = Object.keys(payload.kernelspecs)
|
||||
.map(name => ({
|
||||
.map((name) => ({
|
||||
name,
|
||||
displayName: payload.kernelspecs[name].displayName
|
||||
displayName: payload.kernelspecs[name].displayName,
|
||||
}))
|
||||
.sort((a: KernelSpecsDisplay, b: KernelSpecsDisplay) => {
|
||||
// Put default at the top, otherwise lexicographically compare
|
||||
@@ -229,7 +229,7 @@ export class NotebookClientV2 {
|
||||
dataExplorerArea: Constants.Areas.Notebook,
|
||||
title,
|
||||
message,
|
||||
level: "Error"
|
||||
level: "Error",
|
||||
});
|
||||
console.error(`${title}: ${message}`);
|
||||
};
|
||||
@@ -248,16 +248,16 @@ export class NotebookClientV2 {
|
||||
configOption("autoSaveInterval").action(params.autoSaveInterval ?? Constants.Notebook.autoSaveIntervalMs)
|
||||
);
|
||||
createConfigCollection({
|
||||
key: "monaco"
|
||||
key: "monaco",
|
||||
});
|
||||
defineConfigOption({
|
||||
label: "Show Line numbers",
|
||||
key: "monaco.lineNumbers",
|
||||
values: [
|
||||
{ label: "Yes", value: true },
|
||||
{ label: "No", value: false }
|
||||
{ label: "No", value: false },
|
||||
],
|
||||
defaultValue: true
|
||||
defaultValue: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ export class NotebookClientV2 {
|
||||
dataExplorerArea: Constants.Areas.Notebook,
|
||||
title: msg.title,
|
||||
message: msg.message,
|
||||
level: msg.level
|
||||
level: msg.level,
|
||||
});
|
||||
console.error(`${msg.title}: ${msg.message}`);
|
||||
} else {
|
||||
|
||||
@@ -25,9 +25,9 @@ export class NotebookComponentAdapter extends NotebookComponentBootstrapper impl
|
||||
constructor(options: NotebookComponentAdapterOptions) {
|
||||
super({
|
||||
contentRef: selectors.contentRefByFilepath(options.notebookClient.getStore().getState(), {
|
||||
filepath: options.contentItem.path
|
||||
filepath: options.contentItem.path,
|
||||
}),
|
||||
notebookClient: options.notebookClient
|
||||
notebookClient: options.notebookClient,
|
||||
});
|
||||
|
||||
this.onUpdateKernelInfo = options.onUpdateKernelInfo;
|
||||
@@ -42,7 +42,7 @@ export class NotebookComponentAdapter extends NotebookComponentBootstrapper impl
|
||||
filepath: options.contentItem.path,
|
||||
params: {},
|
||||
kernelRef,
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
ContentRef,
|
||||
KernelRef,
|
||||
NotebookContentRecord,
|
||||
selectors
|
||||
selectors,
|
||||
} from "@nteract/core";
|
||||
import * as Immutable from "immutable";
|
||||
import { Provider } from "react-redux";
|
||||
@@ -58,7 +58,7 @@ export class NotebookComponentBootstrapper {
|
||||
mimetype: null as any,
|
||||
size: 0,
|
||||
writeable: false,
|
||||
type: "notebook"
|
||||
type: "notebook",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,9 +72,7 @@ export class NotebookComponentBootstrapper {
|
||||
}
|
||||
|
||||
public getContent(): { name: string; content: string | ImmutableNotebook } {
|
||||
const record = this.getStore()
|
||||
.getState()
|
||||
.core.entities.contents.byRef.get(this.contentRef);
|
||||
const record = this.getStore().getState().core.entities.contents.byRef.get(this.contentRef);
|
||||
let content: string | ImmutableNotebook;
|
||||
switch (record.model.type) {
|
||||
case "notebook":
|
||||
@@ -89,7 +87,7 @@ export class NotebookComponentBootstrapper {
|
||||
|
||||
return {
|
||||
name: NotebookUtil.getName(record.filepath),
|
||||
content
|
||||
content,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -99,7 +97,7 @@ export class NotebookComponentBootstrapper {
|
||||
filepath: undefined,
|
||||
model: NotebookComponentBootstrapper.wrapModelIntoContent(name, undefined, content),
|
||||
kernelRef: undefined,
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -126,7 +124,7 @@ export class NotebookComponentBootstrapper {
|
||||
public notebookSave(): void {
|
||||
this.getStore().dispatch(
|
||||
actions.save({
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -136,7 +134,7 @@ export class NotebookComponentBootstrapper {
|
||||
actions.changeKernelByName({
|
||||
contentRef: this.contentRef,
|
||||
kernelSpecName,
|
||||
oldKernelRef: this.getCurrentKernelRef()
|
||||
oldKernelRef: this.getCurrentKernelRef(),
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -144,7 +142,7 @@ export class NotebookComponentBootstrapper {
|
||||
public notebookRunAndAdvance(): void {
|
||||
this.getStore().dispatch(
|
||||
CdbActions.executeFocusedCellAndFocusNext({
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -152,7 +150,7 @@ export class NotebookComponentBootstrapper {
|
||||
public notebookRunAll(): void {
|
||||
this.getStore().dispatch(
|
||||
actions.executeAllCells({
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -160,7 +158,7 @@ export class NotebookComponentBootstrapper {
|
||||
public notebookInterruptKernel(): void {
|
||||
this.getStore().dispatch(
|
||||
actions.interruptKernel({
|
||||
kernelRef: this.getCurrentKernelRef()
|
||||
kernelRef: this.getCurrentKernelRef(),
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -169,7 +167,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.killKernel({
|
||||
restarting: false,
|
||||
kernelRef: this.getCurrentKernelRef()
|
||||
kernelRef: this.getCurrentKernelRef(),
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -179,7 +177,7 @@ export class NotebookComponentBootstrapper {
|
||||
actions.restartKernel({
|
||||
kernelRef: this.getCurrentKernelRef(),
|
||||
contentRef: this.contentRef,
|
||||
outputHandling: "None"
|
||||
outputHandling: "None",
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -187,7 +185,7 @@ export class NotebookComponentBootstrapper {
|
||||
public notebookClearAllOutputs(): void {
|
||||
this.getStore().dispatch(
|
||||
actions.clearAllOutputs({
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -196,7 +194,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.createCellBelow({
|
||||
cellType: "code",
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -212,7 +210,7 @@ export class NotebookComponentBootstrapper {
|
||||
actions.changeCellType({
|
||||
id: focusedCellId,
|
||||
contentRef: this.contentRef,
|
||||
to: type
|
||||
to: type,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -227,7 +225,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.copyCell({
|
||||
id: focusedCellId,
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -242,7 +240,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.cutCell({
|
||||
id: focusedCellId,
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -250,7 +248,7 @@ export class NotebookComponentBootstrapper {
|
||||
public notebookPaste(): void {
|
||||
this.getStore().dispatch(
|
||||
actions.pasteCell({
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -263,14 +261,14 @@ export class NotebookComponentBootstrapper {
|
||||
store.dispatch(
|
||||
actions.killKernel({
|
||||
restarting: false,
|
||||
kernelRef
|
||||
kernelRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
store.dispatch(
|
||||
CdbActions.closeNotebook({
|
||||
contentRef: this.contentRef
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
import { ServerConfig, IContentProvider, FileType, IContent, IGetParams } from "@nteract/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { AjaxResponse } from "rxjs/ajax";
|
||||
import { GitHubContentProvider } from "../../../GitHub/GitHubContentProvider";
|
||||
import * as GitHubUtils from "../../../Utils/GitHubUtils";
|
||||
|
||||
export class NotebookContentProvider implements IContentProvider {
|
||||
constructor(private gitHubContentProvider: GitHubContentProvider, private jupyterContentProvider: IContentProvider) {}
|
||||
|
||||
public remove(serverConfig: ServerConfig, path: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).remove(serverConfig, path);
|
||||
}
|
||||
|
||||
public get(serverConfig: ServerConfig, path: string, params: Partial<IGetParams>): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).get(serverConfig, path, params);
|
||||
}
|
||||
|
||||
public update<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>>
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).update(serverConfig, path, model);
|
||||
}
|
||||
|
||||
public create<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>> & { type: FT }
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).create(serverConfig, path, model);
|
||||
}
|
||||
|
||||
public save<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>>
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).save(serverConfig, path, model);
|
||||
}
|
||||
|
||||
public listCheckpoints(serverConfig: ServerConfig, path: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).listCheckpoints(serverConfig, path);
|
||||
}
|
||||
|
||||
public createCheckpoint(serverConfig: ServerConfig, path: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).createCheckpoint(serverConfig, path);
|
||||
}
|
||||
|
||||
public deleteCheckpoint(serverConfig: ServerConfig, path: string, checkpointID: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).deleteCheckpoint(serverConfig, path, checkpointID);
|
||||
}
|
||||
|
||||
public restoreFromCheckpoint(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
checkpointID: string
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).restoreFromCheckpoint(serverConfig, path, checkpointID);
|
||||
}
|
||||
|
||||
private getContentProvider(path: string): IContentProvider {
|
||||
if (GitHubUtils.fromContentUri(path)) {
|
||||
return this.gitHubContentProvider;
|
||||
}
|
||||
|
||||
return this.jupyterContentProvider;
|
||||
}
|
||||
}
|
||||
import { ServerConfig, IContentProvider, FileType, IContent, IGetParams } from "@nteract/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { AjaxResponse } from "rxjs/ajax";
|
||||
import { GitHubContentProvider } from "../../../GitHub/GitHubContentProvider";
|
||||
import * as GitHubUtils from "../../../Utils/GitHubUtils";
|
||||
|
||||
export class NotebookContentProvider implements IContentProvider {
|
||||
constructor(private gitHubContentProvider: GitHubContentProvider, private jupyterContentProvider: IContentProvider) {}
|
||||
|
||||
public remove(serverConfig: ServerConfig, path: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).remove(serverConfig, path);
|
||||
}
|
||||
|
||||
public get(serverConfig: ServerConfig, path: string, params: Partial<IGetParams>): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).get(serverConfig, path, params);
|
||||
}
|
||||
|
||||
public update<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>>
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).update(serverConfig, path, model);
|
||||
}
|
||||
|
||||
public create<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>> & { type: FT }
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).create(serverConfig, path, model);
|
||||
}
|
||||
|
||||
public save<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>>
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).save(serverConfig, path, model);
|
||||
}
|
||||
|
||||
public listCheckpoints(serverConfig: ServerConfig, path: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).listCheckpoints(serverConfig, path);
|
||||
}
|
||||
|
||||
public createCheckpoint(serverConfig: ServerConfig, path: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).createCheckpoint(serverConfig, path);
|
||||
}
|
||||
|
||||
public deleteCheckpoint(serverConfig: ServerConfig, path: string, checkpointID: string): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).deleteCheckpoint(serverConfig, path, checkpointID);
|
||||
}
|
||||
|
||||
public restoreFromCheckpoint(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
checkpointID: string
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).restoreFromCheckpoint(serverConfig, path, checkpointID);
|
||||
}
|
||||
|
||||
private getContentProvider(path: string): IContentProvider {
|
||||
if (GitHubUtils.fromContentUri(path)) {
|
||||
return this.gitHubContentProvider;
|
||||
}
|
||||
|
||||
return this.jupyterContentProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ const makeMapStateToProps = (
|
||||
return {
|
||||
kernelStatus,
|
||||
kernelSpecName,
|
||||
currentCellType
|
||||
currentCellType,
|
||||
} as VirtualCommandBarComponentProps;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ const makeMapStateToProps = (
|
||||
kernelStatus,
|
||||
kernelSpecName,
|
||||
currentCellType,
|
||||
onRender: initialProps.onRender
|
||||
onRender: initialProps.onRender,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ let fakeAjaxResponse: AjaxResponse = {
|
||||
status: 200,
|
||||
response: {},
|
||||
responseText: "",
|
||||
responseType: "json"
|
||||
responseType: "json",
|
||||
};
|
||||
export const sessions = {
|
||||
create: (serverConfig: unknown, body: object): Observable<AjaxResponse> => of(fakeAjaxResponse),
|
||||
__setResponse: (response: AjaxResponse) => {
|
||||
fakeAjaxResponse = response;
|
||||
},
|
||||
createSpy: undefined as any
|
||||
createSpy: undefined as any,
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface CloseNotebookAction {
|
||||
export const closeNotebook = (payload: { contentRef: ContentRef }): CloseNotebookAction => {
|
||||
return {
|
||||
type: CLOSE_NOTEBOOK,
|
||||
payload
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ export const executeFocusedCellAndFocusNext = (payload: {
|
||||
}): ExecuteFocusedCellAndFocusNextAction => {
|
||||
return {
|
||||
type: EXECUTE_FOCUSED_CELL_AND_FOCUS_NEXT,
|
||||
payload
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface UpdateKernelRestartDelayAction {
|
||||
export const UpdateKernelRestartDelay = (payload: { delayMs: number }): UpdateKernelRestartDelayAction => {
|
||||
return {
|
||||
type: UPDATE_KERNEL_RESTART_DELAY,
|
||||
payload
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@ export interface SetHoveredCellAction {
|
||||
export const setHoveredCell = (payload: { cellId: CellId }): SetHoveredCellAction => {
|
||||
return {
|
||||
type: SET_HOVERED_CELL,
|
||||
payload
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ export const traceNotebookTelemetry = (payload: {
|
||||
}): TraceNotebookTelemetryAction => {
|
||||
return {
|
||||
type: TRACE_NOTEBOOK_TELEMETRY,
|
||||
payload
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -100,6 +100,6 @@ export const UpdateNotebookParentDomElt = (payload: {
|
||||
}): UpdateNotebookParentDomEltAction => {
|
||||
return {
|
||||
type: UPDATE_NOTEBOOK_PARENT_DOM_ELTS,
|
||||
payload
|
||||
payload,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -85,7 +85,7 @@ const makeMapStateToProps = (initialState: AppState, initialProps: InitialProps)
|
||||
return {
|
||||
contentRef,
|
||||
mimetype: content.mimetype,
|
||||
type: content.type
|
||||
type: content.type,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ export class TextFile extends React.PureComponent<TextFileProps, TextFileState>
|
||||
constructor(props: TextFileProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
Editor: EditorPlaceholder
|
||||
Editor: EditorPlaceholder,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export class TextFile extends React.PureComponent<TextFileProps, TextFileState>
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
import(/* webpackChunkName: "monaco-editor" */ "@nteract/monaco-editor").then(module => {
|
||||
import(/* webpackChunkName: "monaco-editor" */ "@nteract/monaco-editor").then((module) => {
|
||||
this.setState({ Editor: module.default });
|
||||
});
|
||||
}
|
||||
@@ -99,7 +99,7 @@ function makeMapStateToTextFileProps(
|
||||
return {
|
||||
contentRef,
|
||||
mimetype: content.mimetype != null ? content.mimetype : "text/plain",
|
||||
text
|
||||
text,
|
||||
};
|
||||
};
|
||||
return mapStateToTextFileProps;
|
||||
@@ -117,10 +117,10 @@ const makeMapDispatchToTextFileProps = (
|
||||
dispatch(
|
||||
actions.updateFileText({
|
||||
contentRef,
|
||||
text: source
|
||||
text: source,
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
return mapDispatchToTextFileProps;
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
DirectoryContentRecordProps,
|
||||
DummyContentRecordProps,
|
||||
FileContentRecordProps,
|
||||
NotebookContentRecordProps
|
||||
NotebookContentRecordProps,
|
||||
} from "@nteract/core";
|
||||
import { RecordOf } from "immutable";
|
||||
import * as React from "react";
|
||||
@@ -51,7 +51,7 @@ class Contents extends React.PureComponent<ContentsProps> {
|
||||
OPEN: ["ctrl+o", "meta+o"],
|
||||
PASTE_CELL: ["ctrl+shift+v"],
|
||||
RESTART_KERNEL: ["alt+r r", "alt+r c", "alt+r a"],
|
||||
SAVE: ["ctrl+s", "ctrl+shift+s", "meta+s", "meta+shift+s"]
|
||||
SAVE: ["ctrl+s", "ctrl+shift+s", "meta+s", "meta+shift+s"],
|
||||
};
|
||||
|
||||
render(): JSX.Element {
|
||||
@@ -96,7 +96,7 @@ const makeMapStateToProps: any = (initialState: AppState, initialProps: { conten
|
||||
return {
|
||||
contentRef: undefined,
|
||||
error: undefined,
|
||||
headerData: undefined
|
||||
headerData: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ const makeMapStateToProps: any = (initialState: AppState, initialProps: { conten
|
||||
authors: [],
|
||||
description: "",
|
||||
tags: [],
|
||||
title: ""
|
||||
title: "",
|
||||
};
|
||||
|
||||
// If a notebook, we need to read in the headerData if available
|
||||
@@ -118,14 +118,14 @@ const makeMapStateToProps: any = (initialState: AppState, initialProps: { conten
|
||||
authors,
|
||||
description,
|
||||
tags,
|
||||
title
|
||||
title,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
contentRef,
|
||||
error: content.error,
|
||||
headerData
|
||||
headerData,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -140,7 +140,7 @@ const mapDispatchToProps = (dispatch: Dispatch, ownProps: ContentsProps): object
|
||||
return dispatch(
|
||||
actions.overwriteMetadataFields({
|
||||
...props,
|
||||
contentRef: ownProps.contentRef
|
||||
contentRef: ownProps.contentRef,
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -165,8 +165,8 @@ const mapDispatchToProps = (dispatch: Dispatch, ownProps: ContentsProps): object
|
||||
event.key === "r" ? "None" : event.key === "a" ? "Run All" : "Clear All";
|
||||
return dispatch(actions.restartKernel({ outputHandling, contentRef }));
|
||||
},
|
||||
SAVE: () => dispatch(actions.save({ contentRef }))
|
||||
}
|
||||
SAVE: () => dispatch(actions.save({ contentRef })),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ describe("Extract kernel from notebook", () => {
|
||||
kernelspec: {
|
||||
display_name: "Python 3",
|
||||
language: "python",
|
||||
name: "python3"
|
||||
name: "python3",
|
||||
},
|
||||
language_info: {
|
||||
name: "python",
|
||||
@@ -27,13 +27,13 @@ describe("Extract kernel from notebook", () => {
|
||||
mimetype: "text/x-python",
|
||||
codemirror_mode: {
|
||||
name: "ipython",
|
||||
version: 3
|
||||
version: 3,
|
||||
},
|
||||
pygments_lexer: "ipython3",
|
||||
nbconvert_exporter: "python",
|
||||
file_extension: ".py"
|
||||
}
|
||||
})
|
||||
file_extension: ".py",
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const result = NotebookUtil.extractNewKernel("blah", fakeNotebook);
|
||||
@@ -49,13 +49,13 @@ describe("Extract kernel from notebook", () => {
|
||||
mimetype: "text/x-python",
|
||||
codemirror_mode: {
|
||||
name: "ipython",
|
||||
version: 3
|
||||
version: 3,
|
||||
},
|
||||
pygments_lexer: "ipython3",
|
||||
nbconvert_exporter: "python",
|
||||
file_extension: ".py"
|
||||
}
|
||||
})
|
||||
file_extension: ".py",
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const result = NotebookUtil.extractNewKernel("blah", fakeNotebook);
|
||||
@@ -65,8 +65,8 @@ describe("Extract kernel from notebook", () => {
|
||||
it("Returns nothing if no kernelspec nor language info is found in metadata", () => {
|
||||
const fakeNotebook = makeNotebookRecord({
|
||||
metadata: Immutable.Map({
|
||||
blah: "this should be ignored"
|
||||
})
|
||||
blah: "this should be ignored",
|
||||
}),
|
||||
});
|
||||
|
||||
const result = NotebookUtil.extractNewKernel("blah", fakeNotebook);
|
||||
@@ -79,8 +79,8 @@ const initialState = {
|
||||
host: state.makeJupyterHostRecord({
|
||||
type: "jupyter",
|
||||
token: "eh",
|
||||
basePath: "/"
|
||||
})
|
||||
basePath: "/",
|
||||
}),
|
||||
}),
|
||||
comms: state.makeCommsRecord(),
|
||||
config: Immutable.Map({}),
|
||||
@@ -89,8 +89,8 @@ const initialState = {
|
||||
entities: state.makeEntitiesRecord({
|
||||
contents: state.makeContentsRecord({
|
||||
byRef: Immutable.Map({
|
||||
fakeContentRef: state.makeNotebookContentRecord()
|
||||
})
|
||||
fakeContentRef: state.makeNotebookContentRecord(),
|
||||
}),
|
||||
}),
|
||||
kernels: state.makeKernelsRecord({
|
||||
byRef: Immutable.Map({
|
||||
@@ -98,16 +98,16 @@ const initialState = {
|
||||
type: "websocket",
|
||||
channels: new Subject<any>(),
|
||||
kernelSpecName: "fancy",
|
||||
id: "0"
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
id: "0",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
cdb: makeCdbRecord({
|
||||
databaseAccountName: "dbAccountName",
|
||||
defaultExperience: "defaultExperience"
|
||||
})
|
||||
defaultExperience: "defaultExperience",
|
||||
}),
|
||||
};
|
||||
|
||||
describe("launchWebSocketKernelEpic", () => {
|
||||
@@ -130,7 +130,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -149,20 +149,18 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
connections: 0,
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
name: "",
|
||||
},
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
responseType: "json",
|
||||
});
|
||||
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
expect(responseActions).toMatchObject([
|
||||
{
|
||||
@@ -177,10 +175,10 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
type: "websocket",
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
id: kernelId
|
||||
}
|
||||
}
|
||||
}
|
||||
id: kernelId,
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -198,7 +196,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -217,25 +215,23 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
connections: 0,
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
name: "",
|
||||
},
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
responseType: "json",
|
||||
});
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: kernelSpecName
|
||||
}
|
||||
name: kernelSpecName,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -253,7 +249,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName: undefined,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -272,25 +268,23 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
connections: 0,
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
name: "",
|
||||
},
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
responseType: "json",
|
||||
});
|
||||
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
expect(responseActions).toMatchObject([
|
||||
{
|
||||
type: actions.LAUNCH_KERNEL_FAILED
|
||||
}
|
||||
type: actions.LAUNCH_KERNEL_FAILED,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -304,7 +298,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName: undefined,
|
||||
cwd,
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -315,17 +309,15 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
status: 500,
|
||||
response: null,
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
responseType: "json",
|
||||
});
|
||||
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
const responseActions = await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
expect(responseActions).toMatchObject([
|
||||
{
|
||||
type: actions.LAUNCH_KERNEL_FAILED
|
||||
}
|
||||
type: actions.LAUNCH_KERNEL_FAILED,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -346,7 +338,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
language: "language1",
|
||||
displayName: "Kernel One",
|
||||
metadata: Immutable.Map(),
|
||||
resources: Immutable.Map()
|
||||
resources: Immutable.Map(),
|
||||
}),
|
||||
kernel2: state.makeKernelspec({
|
||||
name: "kernel2",
|
||||
@@ -356,12 +348,12 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
language: "language2",
|
||||
displayName: "Kernel Two",
|
||||
metadata: Immutable.Map(),
|
||||
resources: Immutable.Map()
|
||||
})
|
||||
})
|
||||
})
|
||||
resources: Immutable.Map(),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
refs: Immutable.List(["kernelspecsref"])
|
||||
refs: Immutable.List(["kernelspecsref"]),
|
||||
});
|
||||
initialState.core = initialState.core
|
||||
.setIn(["entities", "kernelspecs"], createKernelSpecsRecord())
|
||||
@@ -383,15 +375,15 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
name: "kernel_launched",
|
||||
last_activity: "2019-11-07T14:29:54.432454Z",
|
||||
execution_state: "starting",
|
||||
connections: 0
|
||||
connections: 0,
|
||||
},
|
||||
notebook: {
|
||||
path: "notebooks/Untitled7.ipynb",
|
||||
name: ""
|
||||
}
|
||||
name: "",
|
||||
},
|
||||
},
|
||||
responseText: null,
|
||||
responseType: "json"
|
||||
responseType: "json",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -404,17 +396,15 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName: "kernel2",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel2"
|
||||
}
|
||||
name: "kernel2",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -427,18 +417,16 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName: undefined,
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel2"
|
||||
}
|
||||
name: "kernel2",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -451,18 +439,16 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName: "This is an unknown kernelspec",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel2"
|
||||
}
|
||||
name: "kernel2",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -475,18 +461,16 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelRef,
|
||||
kernelSpecName: "ernel1",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$)
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
expect(createSpy.lastCall.args[1]).toMatchObject({
|
||||
kernel: {
|
||||
name: "kernel1"
|
||||
}
|
||||
name: "kernel1",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
catchError,
|
||||
first,
|
||||
concatMap,
|
||||
timeout
|
||||
timeout,
|
||||
} from "rxjs/operators";
|
||||
import {
|
||||
AppState,
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
ContentRef,
|
||||
KernelInfo,
|
||||
actions,
|
||||
selectors
|
||||
selectors,
|
||||
} from "@nteract/core";
|
||||
import { message, JupyterMessage, Channels, createMessage, childOf, ofMessageType } from "@nteract/messaging";
|
||||
import { sessions, kernels } from "rx-jupyter";
|
||||
@@ -58,7 +58,7 @@ const logFailureToTelemetry = (state: CdbAppState, title: string, error?: string
|
||||
defaultExperience: state.cdb.defaultExperience,
|
||||
dataExplorerArea: Constants.Areas.Notebook,
|
||||
title,
|
||||
error
|
||||
error,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ const addInitialCodeCellEpic = (
|
||||
): Observable<{} | actions.CreateCellBelow> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FULFILLED),
|
||||
mergeMap(action => {
|
||||
mergeMap((action) => {
|
||||
const state = state$.value;
|
||||
const contentRef = action.payload.contentRef;
|
||||
const model = selectors.model(state, { contentRef });
|
||||
@@ -88,7 +88,7 @@ const addInitialCodeCellEpic = (
|
||||
return of(
|
||||
actions.createCellAppend({
|
||||
cellType: "code",
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -135,8 +135,8 @@ export const acquireKernelInfoEpic = (action$: Observable<actions.NewKernelActio
|
||||
payload: {
|
||||
kernel: { channels },
|
||||
kernelRef,
|
||||
contentRef
|
||||
}
|
||||
contentRef,
|
||||
},
|
||||
} = action;
|
||||
return acquireKernelInfo(channels, kernelRef, contentRef);
|
||||
})
|
||||
@@ -153,7 +153,7 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
childOf(message),
|
||||
ofMessageType("kernel_info_reply"),
|
||||
first(),
|
||||
mergeMap(msg => {
|
||||
mergeMap((msg) => {
|
||||
const content = msg.content;
|
||||
const languageInfo = (content && content.language_info) || {
|
||||
name: "",
|
||||
@@ -162,7 +162,7 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
file_extension: "",
|
||||
pygments_lexer: "",
|
||||
codemirror_mode: "",
|
||||
nbconvert_exporter: ""
|
||||
nbconvert_exporter: "",
|
||||
};
|
||||
|
||||
switch (languageInfo.name) {
|
||||
@@ -186,7 +186,7 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
fileExtension: languageInfo.file_extension,
|
||||
pygmentsLexer: languageInfo.pygments_lexer,
|
||||
codemirrorMode: languageInfo.codemirror_mode,
|
||||
nbconvertExporter: languageInfo.nbconvert_exporter
|
||||
nbconvertExporter: languageInfo.nbconvert_exporter,
|
||||
};
|
||||
|
||||
let result;
|
||||
@@ -197,8 +197,8 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
contentRef,
|
||||
error: new Error(
|
||||
"The kernel that you are attempting to launch does not support the latest version (v5) of the messaging protocol."
|
||||
)
|
||||
})
|
||||
),
|
||||
}),
|
||||
];
|
||||
} else {
|
||||
result = [
|
||||
@@ -206,12 +206,12 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
actions.setLanguageInfo({
|
||||
langInfo: msg.content.language_info,
|
||||
kernelRef,
|
||||
contentRef
|
||||
contentRef,
|
||||
}),
|
||||
actions.setKernelInfo({
|
||||
kernelRef,
|
||||
info
|
||||
})
|
||||
info,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
const connect = (serverConfig: NotebookServiceConfig, kernelID: string, sessionID?: string): Subject<any> => {
|
||||
const wsSubject = webSocket<JupyterMessage>({
|
||||
url: formWebSocketURL(serverConfig, kernelID, sessionID),
|
||||
protocol: serverConfig.wsProtocol
|
||||
protocol: serverConfig.wsProtocol,
|
||||
});
|
||||
|
||||
// Create a subject that does some of the handling inline for the session
|
||||
@@ -249,8 +249,8 @@ const connect = (serverConfig: NotebookServiceConfig, kernelID: string, sessionI
|
||||
...message,
|
||||
header: {
|
||||
session: sessionID,
|
||||
...message.header
|
||||
}
|
||||
...message.header,
|
||||
},
|
||||
};
|
||||
|
||||
wsSubject.next(sessionizedMessage);
|
||||
@@ -297,7 +297,7 @@ export const launchWebSocketKernelEpic = (
|
||||
serverConfig.userPuid = getUserPuid();
|
||||
|
||||
const {
|
||||
payload: { kernelSpecName, cwd, kernelRef, contentRef }
|
||||
payload: { kernelSpecName, cwd, kernelRef, contentRef },
|
||||
} = action;
|
||||
|
||||
const content = selectors.content(state, { contentRef });
|
||||
@@ -321,7 +321,7 @@ export const launchWebSocketKernelEpic = (
|
||||
error: new Error(
|
||||
"Unable to launch kernel: no kernelspec name specified to launch and no default kernelspecs"
|
||||
),
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -330,7 +330,7 @@ export const launchWebSocketKernelEpic = (
|
||||
|
||||
// Find a kernel that best matches the kernel name
|
||||
const match = currentKernelspecs.byName.find(
|
||||
value => value.name.toLowerCase().indexOf(kernelSpecName.toLowerCase()) !== -1
|
||||
(value) => value.name.toLowerCase().indexOf(kernelSpecName.toLowerCase()) !== -1
|
||||
);
|
||||
if (match) {
|
||||
kernelSpecToLaunch = match.name;
|
||||
@@ -346,15 +346,15 @@ export const launchWebSocketKernelEpic = (
|
||||
const sessionPayload = {
|
||||
kernel: {
|
||||
id: null,
|
||||
name: kernelSpecToLaunch
|
||||
name: kernelSpecToLaunch,
|
||||
} as any,
|
||||
name: "",
|
||||
path: content.filepath.replace(/^\/+/g, ""),
|
||||
type: "notebook"
|
||||
type: "notebook",
|
||||
};
|
||||
|
||||
return sessions.create(serverConfig, sessionPayload).pipe(
|
||||
mergeMap(data => {
|
||||
mergeMap((data) => {
|
||||
const session = data.response;
|
||||
|
||||
const sessionId = castToSessionId(session.id);
|
||||
@@ -365,7 +365,7 @@ export const launchWebSocketKernelEpic = (
|
||||
sessionId,
|
||||
cwd,
|
||||
channels: connect(serverConfig, session.kernel.id, sessionId),
|
||||
kernelSpecName: kernelSpecToLaunch
|
||||
kernelSpecName: kernelSpecToLaunch,
|
||||
});
|
||||
|
||||
kernel.channels.next(message({ msg_type: "kernel_info_request" }));
|
||||
@@ -375,11 +375,11 @@ export const launchWebSocketKernelEpic = (
|
||||
kernel,
|
||||
kernelRef,
|
||||
contentRef: action.payload.contentRef,
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
}),
|
||||
catchError(error => {
|
||||
catchError((error) => {
|
||||
return of(actions.launchKernelFailed({ error }));
|
||||
})
|
||||
);
|
||||
@@ -411,7 +411,7 @@ export const restartWebSocketKernelEpic = (
|
||||
actions.restartKernelFailed({
|
||||
error: new Error("Can't execute restart without kernel ref."),
|
||||
kernelRef: "none provided",
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -422,7 +422,7 @@ export const restartWebSocketKernelEpic = (
|
||||
actions.restartKernelFailed({
|
||||
error: new Error("Can't restart a kernel with no Jupyter host."),
|
||||
kernelRef,
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -433,7 +433,7 @@ export const restartWebSocketKernelEpic = (
|
||||
actions.restartKernelFailed({
|
||||
error: new Error("Can't restart a kernel that does not exist."),
|
||||
kernelRef,
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -443,7 +443,7 @@ export const restartWebSocketKernelEpic = (
|
||||
actions.restartKernelFailed({
|
||||
error: new Error("Can only restart Websocket kernels via API."),
|
||||
kernelRef,
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -451,7 +451,7 @@ export const restartWebSocketKernelEpic = (
|
||||
const newKernelRef = createKernelRef();
|
||||
const kill = actions.killKernel({
|
||||
restarting: true,
|
||||
kernelRef
|
||||
kernelRef,
|
||||
});
|
||||
|
||||
const relaunch = actions.launchKernelByName({
|
||||
@@ -459,7 +459,7 @@ export const restartWebSocketKernelEpic = (
|
||||
cwd: kernel.cwd,
|
||||
kernelRef: newKernelRef,
|
||||
selectNextKernel: true,
|
||||
contentRef: contentRef
|
||||
contentRef: contentRef,
|
||||
});
|
||||
|
||||
const awaitKernelReady = action$.pipe(
|
||||
@@ -470,7 +470,7 @@ export const restartWebSocketKernelEpic = (
|
||||
concatMap(() => {
|
||||
const restartSuccess = actions.restartKernelSuccessful({
|
||||
kernelRef: newKernelRef,
|
||||
contentRef
|
||||
contentRef,
|
||||
});
|
||||
|
||||
if ((action as actions.RestartKernel).payload.outputHandling === "Run All") {
|
||||
@@ -479,12 +479,12 @@ export const restartWebSocketKernelEpic = (
|
||||
return of(restartSuccess);
|
||||
}
|
||||
}),
|
||||
catchError(error => {
|
||||
catchError((error) => {
|
||||
return of(
|
||||
actions.restartKernelFailed({
|
||||
error,
|
||||
kernelRef: newKernelRef,
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
})
|
||||
@@ -511,7 +511,7 @@ const changeWebSocketKernelEpic = (
|
||||
filter(() => selectors.isCurrentHostJupyter(state$.value)),
|
||||
switchMap((action: actions.ChangeKernelByName) => {
|
||||
const {
|
||||
payload: { contentRef, oldKernelRef, kernelSpecName }
|
||||
payload: { contentRef, oldKernelRef, kernelSpecName },
|
||||
} = action;
|
||||
const state = state$.value;
|
||||
const host = selectors.currentHost(state);
|
||||
@@ -539,7 +539,7 @@ const changeWebSocketKernelEpic = (
|
||||
}
|
||||
const {
|
||||
filepath,
|
||||
model: { notebook }
|
||||
model: { notebook },
|
||||
} = content;
|
||||
const { cwd } = NotebookUtil.extractNewKernel(filepath, notebook);
|
||||
|
||||
@@ -548,7 +548,7 @@ const changeWebSocketKernelEpic = (
|
||||
mergeMap(({ response }) => {
|
||||
const { id: kernelId } = response;
|
||||
const sessionPayload = {
|
||||
kernel: { id: kernelId, name: kernelSpecName }
|
||||
kernel: { id: kernelId, name: kernelSpecName },
|
||||
};
|
||||
// The sessions API will close down the old kernel for us if it is on this session
|
||||
return sessions.update(serverConfig, sessionId, sessionPayload).pipe(
|
||||
@@ -558,21 +558,21 @@ const changeWebSocketKernelEpic = (
|
||||
sessionId,
|
||||
cwd,
|
||||
channels: connect(serverConfig, session.kernel.id, sessionId),
|
||||
kernelSpecName
|
||||
kernelSpecName,
|
||||
});
|
||||
return of(
|
||||
actions.launchKernelSuccessful({
|
||||
kernel,
|
||||
kernelRef,
|
||||
contentRef: action.payload.contentRef,
|
||||
selectNextKernel: true
|
||||
selectNextKernel: true,
|
||||
})
|
||||
);
|
||||
}),
|
||||
catchError(error => of(actions.launchKernelFailed({ error, kernelRef, contentRef })))
|
||||
catchError((error) => of(actions.launchKernelFailed({ error, kernelRef, contentRef })))
|
||||
);
|
||||
}),
|
||||
catchError(error => of(actions.launchKernelFailed({ error, kernelRef, contentRef })))
|
||||
catchError((error) => of(actions.launchKernelFailed({ error, kernelRef, contentRef })))
|
||||
);
|
||||
})
|
||||
);
|
||||
@@ -589,7 +589,7 @@ const focusInitialCodeCellEpic = (
|
||||
): Observable<{} | actions.FocusCell> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.CREATE_CELL_APPEND),
|
||||
mergeMap(action => {
|
||||
mergeMap((action) => {
|
||||
const state = state$.value;
|
||||
const contentRef = action.payload.contentRef;
|
||||
const model = selectors.model(state, { contentRef });
|
||||
@@ -606,7 +606,7 @@ const focusInitialCodeCellEpic = (
|
||||
return of(
|
||||
actions.focusCell({
|
||||
id,
|
||||
contentRef
|
||||
contentRef,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -631,7 +631,7 @@ const notificationsToUserEpic = (action$: Observable<any>, state$: StateObservab
|
||||
actions.SAVE_FAILED,
|
||||
actions.FETCH_CONTENT_FAILED
|
||||
),
|
||||
mergeMap(action => {
|
||||
mergeMap((action) => {
|
||||
switch (action.type) {
|
||||
case actions.RESTART_KERNEL_SUCCESSFUL: {
|
||||
const title = "Kernel restart";
|
||||
@@ -677,7 +677,7 @@ const handleKernelConnectionLostEpic = (
|
||||
): Observable<CdbActions.UpdateKernelRestartDelayAction | actions.RestartKernel | {}> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.UPDATE_DISPLAY_FAILED),
|
||||
mergeMap(action => {
|
||||
mergeMap((action) => {
|
||||
const state = state$.value;
|
||||
|
||||
const msg = "Notebook was disconnected from kernel";
|
||||
@@ -708,14 +708,14 @@ const handleKernelConnectionLostEpic = (
|
||||
of(CdbActions.UpdateKernelRestartDelay({ delayMs: delayMs * 1.5 })),
|
||||
sessions.list(serverConfig).pipe(
|
||||
delayWhen(() => timer(delayMs)),
|
||||
map(xhr => {
|
||||
map((xhr) => {
|
||||
return actions.restartKernel({
|
||||
outputHandling: "None",
|
||||
kernelRef,
|
||||
contentRef
|
||||
contentRef,
|
||||
});
|
||||
}),
|
||||
retryWhen(errors => {
|
||||
retryWhen((errors) => {
|
||||
return errors.pipe(
|
||||
delayWhen(() => timer(Constants.Notebook.heartbeatDelayMs)),
|
||||
tap(() => console.log("retrying...")) // TODO: Send new action?
|
||||
@@ -738,12 +738,12 @@ export const cleanKernelOnConnectionLostEpic = (
|
||||
): Observable<actions.KillKernelSuccessful> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.UPDATE_DISPLAY_FAILED),
|
||||
switchMap(action => {
|
||||
switchMap((action) => {
|
||||
const contentRef = action.payload.contentRef;
|
||||
const kernelRef = selectors.kernelRefByContentRef(state$.value, { contentRef });
|
||||
return of(
|
||||
actions.killKernelSuccessful({
|
||||
kernelRef
|
||||
kernelRef,
|
||||
})
|
||||
);
|
||||
})
|
||||
@@ -761,7 +761,7 @@ const executeFocusedCellAndFocusNextEpic = (
|
||||
): Observable<{} | actions.FocusNextCellEditor> => {
|
||||
return action$.pipe(
|
||||
ofType(CdbActions.EXECUTE_FOCUSED_CELL_AND_FOCUS_NEXT),
|
||||
mergeMap(action => {
|
||||
mergeMap((action) => {
|
||||
const contentRef = action.payload.contentRef;
|
||||
return concat(
|
||||
of(actions.executeFocusedCell({ contentRef })),
|
||||
@@ -801,7 +801,7 @@ const closeUnsupportedMimetypesEpic = (
|
||||
): Observable<{}> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FULFILLED),
|
||||
mergeMap(action => {
|
||||
mergeMap((action) => {
|
||||
const mimetype = action.payload.model.mimetype;
|
||||
const explorer = window.dataExplorer;
|
||||
if (explorer && !TextFile.handles(mimetype)) {
|
||||
@@ -830,7 +830,7 @@ const closeContentFailedToFetchEpic = (
|
||||
): Observable<{}> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FAILED),
|
||||
mergeMap(action => {
|
||||
mergeMap((action) => {
|
||||
const explorer = window.dataExplorer;
|
||||
if (explorer) {
|
||||
const filepath = action.payload.filepath;
|
||||
@@ -860,7 +860,7 @@ const traceNotebookTelemetryEpic = (
|
||||
...action.payload.data,
|
||||
databaseAccountName: state.cdb.databaseAccountName,
|
||||
defaultExperience: state.cdb.defaultExperience,
|
||||
dataExplorerArea: Areas.Notebook
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
});
|
||||
return EMPTY;
|
||||
})
|
||||
@@ -893,7 +893,7 @@ const traceNotebookInfoEpic = (
|
||||
nbCodeCells: 0,
|
||||
nbRawCells: 0,
|
||||
nbMarkdownCells: 0,
|
||||
nbCells: 0
|
||||
nbCells: 0,
|
||||
};
|
||||
for (let [id, cell] of selectors.notebook.cellMap(model)) {
|
||||
switch (cell.cell_type) {
|
||||
@@ -914,7 +914,7 @@ const traceNotebookInfoEpic = (
|
||||
cdbActions.traceNotebookTelemetry({
|
||||
action: TelemetryAction.NotebooksFetched,
|
||||
actionModifier: ActionModifiers.Mark,
|
||||
data: dataToLog
|
||||
data: dataToLog,
|
||||
})
|
||||
);
|
||||
})
|
||||
@@ -938,8 +938,8 @@ const traceNotebookKernelEpic = (
|
||||
action: TelemetryAction.NotebooksKernelSpecName,
|
||||
actionModifier: ActionModifiers.Mark,
|
||||
data: {
|
||||
kernelSpecName: action.payload.kernel.name
|
||||
}
|
||||
kernelSpecName: action.payload.kernel.name,
|
||||
},
|
||||
})
|
||||
);
|
||||
})
|
||||
@@ -961,5 +961,5 @@ export const allEpics = [
|
||||
restartWebSocketKernelEpic,
|
||||
traceNotebookTelemetryEpic,
|
||||
traceNotebookInfoEpic,
|
||||
traceNotebookKernelEpic
|
||||
traceNotebookKernelEpic,
|
||||
];
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
// https://github.com/nteract/nteract/blob/master/applications/jupyter-extension/nteract_on_jupyter/app/contents/notebook.tsx
|
||||
|
||||
export default (props: { addTransform: (component: any) => void }) => {
|
||||
import(/* webpackChunkName: "plotly" */ "@nteract/transform-plotly").then(module => {
|
||||
import(/* webpackChunkName: "plotly" */ "@nteract/transform-plotly").then((module) => {
|
||||
props.addTransform(module.default);
|
||||
props.addTransform(module.PlotlyNullTransform);
|
||||
});
|
||||
|
||||
import(/* webpackChunkName: "tabular-dataresource" */ "@nteract/data-explorer").then(module => {
|
||||
import(/* webpackChunkName: "tabular-dataresource" */ "@nteract/data-explorer").then((module) => {
|
||||
props.addTransform(module.default);
|
||||
});
|
||||
|
||||
import(/* webpackChunkName: "jupyter-widgets" */ "@nteract/jupyter-widgets").then(module => {
|
||||
import(/* webpackChunkName: "jupyter-widgets" */ "@nteract/jupyter-widgets").then((module) => {
|
||||
props.addTransform(module.WidgetDisplay);
|
||||
});
|
||||
|
||||
import("@nteract/transform-model-debug").then(module => {
|
||||
import("@nteract/transform-model-debug").then((module) => {
|
||||
props.addTransform(module.default);
|
||||
});
|
||||
|
||||
import(/* webpackChunkName: "vega-transform" */ "@nteract/transform-vega").then(module => {
|
||||
import(/* webpackChunkName: "vega-transform" */ "@nteract/transform-vega").then((module) => {
|
||||
props.addTransform(module.VegaLite1);
|
||||
props.addTransform(module.VegaLite2);
|
||||
props.addTransform(module.VegaLite3);
|
||||
|
||||
@@ -41,7 +41,7 @@ export const coreReducer = (state: CoreRecord, action: Action) => {
|
||||
"model",
|
||||
"notebook",
|
||||
"metadata",
|
||||
"kernelspec"
|
||||
"kernelspec",
|
||||
];
|
||||
// Update metadata
|
||||
return state
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function configureStore(
|
||||
*/
|
||||
const catchErrorMiddleware: Middleware = <D extends Dispatch<AnyAction>, S extends AppState>({
|
||||
dispatch,
|
||||
getState
|
||||
getState,
|
||||
}: MiddlewareAPI<D, S>) => (next: Dispatch<AnyAction>) => <A extends AnyAction>(action: A): any => {
|
||||
try {
|
||||
next(action);
|
||||
@@ -52,7 +52,7 @@ export default function configureStore(
|
||||
};
|
||||
|
||||
const protectEpics = (epics: Epic[]): Epic[] => {
|
||||
return epics.map(epic => protect(epic));
|
||||
return epics.map((epic) => protect(epic));
|
||||
};
|
||||
|
||||
const filteredCoreEpics = getCoreEpics(autoStartKernelOnNotebookOpen);
|
||||
@@ -62,12 +62,12 @@ export default function configureStore(
|
||||
reducers: {
|
||||
app: reducers.app,
|
||||
core: coreReducer as any,
|
||||
cdb: cdbReducer
|
||||
cdb: cdbReducer,
|
||||
},
|
||||
epics: protectEpics([...filteredCoreEpics, ...allEpics]),
|
||||
epicDependencies: { contentProvider },
|
||||
epicMiddleware: customMiddlewares.concat(catchErrorMiddleware),
|
||||
enhancer: composeEnhancers
|
||||
enhancer: composeEnhancers,
|
||||
});
|
||||
|
||||
const store = mythConfigureStore(initialState as any);
|
||||
@@ -100,7 +100,7 @@ export const getCoreEpics = (autoStartKernelOnNotebookOpen: boolean): Epic[] =>
|
||||
coreEpics.saveContentEpic,
|
||||
coreEpics.publishToBookstore,
|
||||
coreEpics.publishToBookstoreAfterSave,
|
||||
coreEpics.sendInputReplyEpic
|
||||
coreEpics.sendInputReplyEpic,
|
||||
];
|
||||
|
||||
if (autoStartKernelOnNotebookOpen) {
|
||||
|
||||
@@ -23,5 +23,5 @@ export const makeCdbRecord = Immutable.Record<CdbRecordProps>({
|
||||
defaultExperience: undefined,
|
||||
kernelRestartDelayMs: Notebook.kernelRestartInitialDelayMs,
|
||||
hoveredCellId: undefined,
|
||||
currentNotebookParentElements: new Map<ContentRef, HTMLElement>()
|
||||
currentNotebookParentElements: new Map<ContentRef, HTMLElement>(),
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ export class NotebookContainerClient {
|
||||
private scheduleHeartbeat(delayMs: number): void {
|
||||
setTimeout(() => {
|
||||
this.getMemoryUsage()
|
||||
.then(memoryUsageInfo => this.onMemoryUsageInfoUpdate(memoryUsageInfo))
|
||||
.then((memoryUsageInfo) => this.onMemoryUsageInfoUpdate(memoryUsageInfo))
|
||||
.finally(() => this.scheduleHeartbeat(Constants.Notebook.heartbeatDelayMs));
|
||||
}, delayMs);
|
||||
}
|
||||
@@ -57,8 +57,8 @@ export class NotebookContainerClient {
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: authToken,
|
||||
"content-type": "application/json"
|
||||
}
|
||||
"content-type": "application/json",
|
||||
},
|
||||
});
|
||||
if (response.ok) {
|
||||
if (this.reconnectingNotificationId) {
|
||||
@@ -69,7 +69,7 @@ export class NotebookContainerClient {
|
||||
if (memoryUsageInfo) {
|
||||
return {
|
||||
totalKB: memoryUsageInfo.total,
|
||||
freeKB: memoryUsageInfo.free
|
||||
freeKB: memoryUsageInfo.free,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ export class NotebookContainerClient {
|
||||
try {
|
||||
await fetch(`${notebookServerEndpoint}/api/shutdown`, {
|
||||
method: "POST",
|
||||
headers: { Authorization: authToken }
|
||||
headers: { Authorization: authToken },
|
||||
});
|
||||
} catch (error) {
|
||||
Logger.logError(getErrorMessage(error), "NotebookContainerClient/resetWorkspace");
|
||||
@@ -126,7 +126,7 @@ export class NotebookContainerClient {
|
||||
|
||||
return {
|
||||
notebookServerEndpoint,
|
||||
authToken
|
||||
authToken,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ export class NotebookContentClient {
|
||||
* @param item
|
||||
*/
|
||||
public updateItemChildren(item: NotebookContentItem): Promise<void> {
|
||||
return this.fetchNotebookFiles(item.path).then(subItems => {
|
||||
return this.fetchNotebookFiles(item.path).then((subItems) => {
|
||||
item.children = subItems;
|
||||
subItems.forEach(subItem => (subItem.parent = item));
|
||||
subItems.forEach((subItem) => (subItem.parent = item));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export class NotebookContentClient {
|
||||
|
||||
if (item.parent && item.parent.children) {
|
||||
// Remove deleted child
|
||||
const newChildren = item.parent.children.filter(child => child.path !== path);
|
||||
const newChildren = item.parent.children.filter((child) => child.path !== path);
|
||||
item.parent.children = newChildren;
|
||||
}
|
||||
});
|
||||
@@ -98,7 +98,7 @@ export class NotebookContentClient {
|
||||
content,
|
||||
format: "text",
|
||||
name,
|
||||
type: "file"
|
||||
type: "file",
|
||||
};
|
||||
|
||||
return this.contentProvider
|
||||
@@ -119,7 +119,7 @@ export class NotebookContentClient {
|
||||
const parentDirPath = NotebookUtil.getParentPath(filepath);
|
||||
if (parentDirPath) {
|
||||
const items = await this.fetchNotebookFiles(parentDirPath);
|
||||
return items.some(value => FileSystemUtil.isPathEqual(value.path, filepath));
|
||||
return items.some((value) => FileSystemUtil.isPathEqual(value.path, filepath));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -142,7 +142,7 @@ export class NotebookContentClient {
|
||||
return this.contentProvider
|
||||
.update<"file" | "notebook" | "directory">(this.getServerConfig(), sourcePath, { path: targetPath })
|
||||
.toPromise()
|
||||
.then(xhr => {
|
||||
.then((xhr) => {
|
||||
if (typeof xhr.response === "string") {
|
||||
throw new Error(`jupyter server response invalid: ${xhr.response}`);
|
||||
}
|
||||
@@ -244,10 +244,10 @@ export class NotebookContentClient {
|
||||
private fetchNotebookFiles(path: string): Promise<NotebookContentItem[]> {
|
||||
return this.contentProvider
|
||||
.get(this.getServerConfig(), path, {
|
||||
type: "directory"
|
||||
type: "directory",
|
||||
})
|
||||
.toPromise()
|
||||
.then(xhr => {
|
||||
.then((xhr) => {
|
||||
if (xhr.status !== 200) {
|
||||
throw new Error(JSON.stringify(xhr.response));
|
||||
}
|
||||
@@ -265,7 +265,7 @@ export class NotebookContentClient {
|
||||
(item: IEmptyContent<FileType>): NotebookContentItem => ({
|
||||
name: item.name,
|
||||
path: item.path,
|
||||
type: NotebookUtil.getType(item.type)
|
||||
type: NotebookUtil.getType(item.type),
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -275,7 +275,7 @@ export class NotebookContentClient {
|
||||
return {
|
||||
endpoint: this.notebookServerInfo().notebookServerEndpoint,
|
||||
token: this.notebookServerInfo().authToken,
|
||||
crossDomain: true
|
||||
crossDomain: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@ export interface NotebookContentItem {
|
||||
export enum NotebookContentItemType {
|
||||
Notebook,
|
||||
File,
|
||||
Directory
|
||||
Directory,
|
||||
}
|
||||
|
||||
@@ -1,194 +1,194 @@
|
||||
/*
|
||||
* Contains all notebook related stuff meant to be dynamically loaded by explorer
|
||||
*/
|
||||
|
||||
import { JunoClient } from "../../Juno/JunoClient";
|
||||
import { GitHubOAuthService } from "../../GitHub/GitHubOAuthService";
|
||||
import { GitHubClient } from "../../GitHub/GitHubClient";
|
||||
import * as Logger from "../../Common/Logger";
|
||||
import { HttpStatusCodes, Areas } from "../../Common/Constants";
|
||||
import { GitHubReposPane } from "../Panes/GitHubReposPane";
|
||||
import ko from "knockout";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import { IContentProvider } from "@nteract/core";
|
||||
import { NotebookContentProvider } from "./NotebookComponent/NotebookContentProvider";
|
||||
import { GitHubContentProvider } from "../../GitHub/GitHubContentProvider";
|
||||
import { contents } from "rx-jupyter";
|
||||
import { NotebookContainerClient } from "./NotebookContainerClient";
|
||||
import { MemoryUsageInfo } from "../../Contracts/DataModels";
|
||||
import { NotebookContentClient } from "./NotebookContentClient";
|
||||
import { DialogProps } from "../Controls/DialogReactComponent/DialogComponent";
|
||||
import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter";
|
||||
import { PublishNotebookPaneAdapter } from "../Panes/PublishNotebookPaneAdapter";
|
||||
import { getFullName } from "../../Utils/UserUtils";
|
||||
import { ImmutableNotebook } from "@nteract/commutable";
|
||||
import Explorer from "../Explorer";
|
||||
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
||||
import { CopyNotebookPaneAdapter } from "../Panes/CopyNotebookPane";
|
||||
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||
|
||||
export interface NotebookManagerOptions {
|
||||
container: Explorer;
|
||||
notebookBasePath: ko.Observable<string>;
|
||||
dialogProps: ko.Observable<DialogProps>;
|
||||
resourceTree: ResourceTreeAdapter;
|
||||
refreshCommandBarButtons: () => void;
|
||||
refreshNotebookList: () => void;
|
||||
}
|
||||
|
||||
export default class NotebookManager {
|
||||
private params: NotebookManagerOptions;
|
||||
public junoClient: JunoClient;
|
||||
|
||||
public notebookContentProvider: IContentProvider;
|
||||
public notebookClient: NotebookContainerClient;
|
||||
public notebookContentClient: NotebookContentClient;
|
||||
|
||||
private gitHubContentProvider: GitHubContentProvider;
|
||||
public gitHubOAuthService: GitHubOAuthService;
|
||||
private gitHubClient: GitHubClient;
|
||||
|
||||
public gitHubReposPane: ContextualPaneBase;
|
||||
public publishNotebookPaneAdapter: PublishNotebookPaneAdapter;
|
||||
public copyNotebookPaneAdapter: CopyNotebookPaneAdapter;
|
||||
|
||||
public initialize(params: NotebookManagerOptions): void {
|
||||
this.params = params;
|
||||
this.junoClient = new JunoClient(this.params.container.databaseAccount);
|
||||
|
||||
this.gitHubOAuthService = new GitHubOAuthService(this.junoClient);
|
||||
this.gitHubClient = new GitHubClient(this.onGitHubClientError);
|
||||
this.gitHubReposPane = new GitHubReposPane({
|
||||
id: "gitHubReposPane",
|
||||
visible: ko.observable<boolean>(false),
|
||||
container: this.params.container,
|
||||
junoClient: this.junoClient,
|
||||
gitHubClient: this.gitHubClient
|
||||
});
|
||||
|
||||
this.gitHubContentProvider = new GitHubContentProvider({
|
||||
gitHubClient: this.gitHubClient,
|
||||
promptForCommitMsg: this.promptForCommitMsg
|
||||
});
|
||||
|
||||
this.notebookContentProvider = new NotebookContentProvider(
|
||||
this.gitHubContentProvider,
|
||||
contents.JupyterContentProvider
|
||||
);
|
||||
|
||||
this.notebookClient = new NotebookContainerClient(
|
||||
this.params.container.notebookServerInfo,
|
||||
() => this.params.container.initNotebooks(this.params.container.databaseAccount()),
|
||||
(update: MemoryUsageInfo) => this.params.container.memoryUsageInfo(update)
|
||||
);
|
||||
|
||||
this.notebookContentClient = new NotebookContentClient(
|
||||
this.params.container.notebookServerInfo,
|
||||
this.params.notebookBasePath,
|
||||
this.notebookContentProvider
|
||||
);
|
||||
|
||||
if (this.params.container.isGalleryPublishEnabled()) {
|
||||
this.publishNotebookPaneAdapter = new PublishNotebookPaneAdapter(this.params.container, this.junoClient);
|
||||
}
|
||||
|
||||
this.copyNotebookPaneAdapter = new CopyNotebookPaneAdapter(
|
||||
this.params.container,
|
||||
this.junoClient,
|
||||
this.gitHubOAuthService
|
||||
);
|
||||
|
||||
this.gitHubOAuthService.getTokenObservable().subscribe(token => {
|
||||
this.gitHubClient.setToken(token?.access_token);
|
||||
|
||||
if (this.gitHubReposPane.visible()) {
|
||||
this.gitHubReposPane.open();
|
||||
}
|
||||
|
||||
this.params.refreshCommandBarButtons();
|
||||
this.params.refreshNotebookList();
|
||||
});
|
||||
|
||||
this.junoClient.subscribeToPinnedRepos(pinnedRepos => {
|
||||
this.params.resourceTree.initializeGitHubRepos(pinnedRepos);
|
||||
this.params.resourceTree.triggerRender();
|
||||
});
|
||||
this.refreshPinnedRepos();
|
||||
}
|
||||
|
||||
public refreshPinnedRepos(): void {
|
||||
const token = this.gitHubOAuthService.getTokenObservable()();
|
||||
if (token) {
|
||||
this.junoClient.getPinnedRepos(token.scope);
|
||||
}
|
||||
}
|
||||
|
||||
public async openPublishNotebookPane(
|
||||
name: string,
|
||||
content: string | ImmutableNotebook,
|
||||
parentDomElement: HTMLElement,
|
||||
isLinkInjectionEnabled: boolean
|
||||
): Promise<void> {
|
||||
await this.publishNotebookPaneAdapter.open(name, getFullName(), content, parentDomElement, isLinkInjectionEnabled);
|
||||
}
|
||||
|
||||
public openCopyNotebookPane(name: string, content: string): void {
|
||||
this.copyNotebookPaneAdapter.open(name, content);
|
||||
}
|
||||
|
||||
// Octokit's error handler uses any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private onGitHubClientError = (error: any): void => {
|
||||
Logger.logError(getErrorMessage(error), "NotebookManager/onGitHubClientError");
|
||||
|
||||
if (error.status === HttpStatusCodes.Unauthorized) {
|
||||
this.gitHubOAuthService.resetToken();
|
||||
|
||||
this.params.container.showOkCancelModalDialog(
|
||||
undefined,
|
||||
"Cosmos DB cannot access your Github account anymore. Please connect to GitHub again.",
|
||||
"Connect to GitHub",
|
||||
() => this.gitHubReposPane.open(),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private promptForCommitMsg = (title: string, primaryButtonLabel: string) => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
let commitMsg = "Committed from Azure Cosmos DB Notebooks";
|
||||
this.params.container.showOkCancelModalDialog(
|
||||
title || "Commit",
|
||||
undefined,
|
||||
primaryButtonLabel || "Commit",
|
||||
() => {
|
||||
TelemetryProcessor.trace(Action.NotebooksGitHubCommit, ActionModifiers.Mark, {
|
||||
databaseAccountName:
|
||||
this.params.container.databaseAccount() && this.params.container.databaseAccount().name,
|
||||
defaultExperience: this.params.container.defaultExperience && this.params.container.defaultExperience(),
|
||||
dataExplorerArea: Areas.Notebook
|
||||
});
|
||||
resolve(commitMsg);
|
||||
},
|
||||
"Cancel",
|
||||
() => reject(new Error("Commit dialog canceled")),
|
||||
undefined,
|
||||
{
|
||||
label: "Commit message",
|
||||
autoAdjustHeight: true,
|
||||
multiline: true,
|
||||
defaultValue: commitMsg,
|
||||
rows: 3,
|
||||
onChange: (_, newValue: string) => {
|
||||
commitMsg = newValue;
|
||||
this.params.dialogProps().primaryButtonDisabled = !commitMsg;
|
||||
this.params.dialogProps.valueHasMutated();
|
||||
}
|
||||
},
|
||||
!commitMsg
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Contains all notebook related stuff meant to be dynamically loaded by explorer
|
||||
*/
|
||||
|
||||
import { JunoClient } from "../../Juno/JunoClient";
|
||||
import { GitHubOAuthService } from "../../GitHub/GitHubOAuthService";
|
||||
import { GitHubClient } from "../../GitHub/GitHubClient";
|
||||
import * as Logger from "../../Common/Logger";
|
||||
import { HttpStatusCodes, Areas } from "../../Common/Constants";
|
||||
import { GitHubReposPane } from "../Panes/GitHubReposPane";
|
||||
import ko from "knockout";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import { IContentProvider } from "@nteract/core";
|
||||
import { NotebookContentProvider } from "./NotebookComponent/NotebookContentProvider";
|
||||
import { GitHubContentProvider } from "../../GitHub/GitHubContentProvider";
|
||||
import { contents } from "rx-jupyter";
|
||||
import { NotebookContainerClient } from "./NotebookContainerClient";
|
||||
import { MemoryUsageInfo } from "../../Contracts/DataModels";
|
||||
import { NotebookContentClient } from "./NotebookContentClient";
|
||||
import { DialogProps } from "../Controls/DialogReactComponent/DialogComponent";
|
||||
import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter";
|
||||
import { PublishNotebookPaneAdapter } from "../Panes/PublishNotebookPaneAdapter";
|
||||
import { getFullName } from "../../Utils/UserUtils";
|
||||
import { ImmutableNotebook } from "@nteract/commutable";
|
||||
import Explorer from "../Explorer";
|
||||
import { ContextualPaneBase } from "../Panes/ContextualPaneBase";
|
||||
import { CopyNotebookPaneAdapter } from "../Panes/CopyNotebookPane";
|
||||
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||
|
||||
export interface NotebookManagerOptions {
|
||||
container: Explorer;
|
||||
notebookBasePath: ko.Observable<string>;
|
||||
dialogProps: ko.Observable<DialogProps>;
|
||||
resourceTree: ResourceTreeAdapter;
|
||||
refreshCommandBarButtons: () => void;
|
||||
refreshNotebookList: () => void;
|
||||
}
|
||||
|
||||
export default class NotebookManager {
|
||||
private params: NotebookManagerOptions;
|
||||
public junoClient: JunoClient;
|
||||
|
||||
public notebookContentProvider: IContentProvider;
|
||||
public notebookClient: NotebookContainerClient;
|
||||
public notebookContentClient: NotebookContentClient;
|
||||
|
||||
private gitHubContentProvider: GitHubContentProvider;
|
||||
public gitHubOAuthService: GitHubOAuthService;
|
||||
private gitHubClient: GitHubClient;
|
||||
|
||||
public gitHubReposPane: ContextualPaneBase;
|
||||
public publishNotebookPaneAdapter: PublishNotebookPaneAdapter;
|
||||
public copyNotebookPaneAdapter: CopyNotebookPaneAdapter;
|
||||
|
||||
public initialize(params: NotebookManagerOptions): void {
|
||||
this.params = params;
|
||||
this.junoClient = new JunoClient(this.params.container.databaseAccount);
|
||||
|
||||
this.gitHubOAuthService = new GitHubOAuthService(this.junoClient);
|
||||
this.gitHubClient = new GitHubClient(this.onGitHubClientError);
|
||||
this.gitHubReposPane = new GitHubReposPane({
|
||||
id: "gitHubReposPane",
|
||||
visible: ko.observable<boolean>(false),
|
||||
container: this.params.container,
|
||||
junoClient: this.junoClient,
|
||||
gitHubClient: this.gitHubClient,
|
||||
});
|
||||
|
||||
this.gitHubContentProvider = new GitHubContentProvider({
|
||||
gitHubClient: this.gitHubClient,
|
||||
promptForCommitMsg: this.promptForCommitMsg,
|
||||
});
|
||||
|
||||
this.notebookContentProvider = new NotebookContentProvider(
|
||||
this.gitHubContentProvider,
|
||||
contents.JupyterContentProvider
|
||||
);
|
||||
|
||||
this.notebookClient = new NotebookContainerClient(
|
||||
this.params.container.notebookServerInfo,
|
||||
() => this.params.container.initNotebooks(this.params.container.databaseAccount()),
|
||||
(update: MemoryUsageInfo) => this.params.container.memoryUsageInfo(update)
|
||||
);
|
||||
|
||||
this.notebookContentClient = new NotebookContentClient(
|
||||
this.params.container.notebookServerInfo,
|
||||
this.params.notebookBasePath,
|
||||
this.notebookContentProvider
|
||||
);
|
||||
|
||||
if (this.params.container.isGalleryPublishEnabled()) {
|
||||
this.publishNotebookPaneAdapter = new PublishNotebookPaneAdapter(this.params.container, this.junoClient);
|
||||
}
|
||||
|
||||
this.copyNotebookPaneAdapter = new CopyNotebookPaneAdapter(
|
||||
this.params.container,
|
||||
this.junoClient,
|
||||
this.gitHubOAuthService
|
||||
);
|
||||
|
||||
this.gitHubOAuthService.getTokenObservable().subscribe((token) => {
|
||||
this.gitHubClient.setToken(token?.access_token);
|
||||
|
||||
if (this.gitHubReposPane.visible()) {
|
||||
this.gitHubReposPane.open();
|
||||
}
|
||||
|
||||
this.params.refreshCommandBarButtons();
|
||||
this.params.refreshNotebookList();
|
||||
});
|
||||
|
||||
this.junoClient.subscribeToPinnedRepos((pinnedRepos) => {
|
||||
this.params.resourceTree.initializeGitHubRepos(pinnedRepos);
|
||||
this.params.resourceTree.triggerRender();
|
||||
});
|
||||
this.refreshPinnedRepos();
|
||||
}
|
||||
|
||||
public refreshPinnedRepos(): void {
|
||||
const token = this.gitHubOAuthService.getTokenObservable()();
|
||||
if (token) {
|
||||
this.junoClient.getPinnedRepos(token.scope);
|
||||
}
|
||||
}
|
||||
|
||||
public async openPublishNotebookPane(
|
||||
name: string,
|
||||
content: string | ImmutableNotebook,
|
||||
parentDomElement: HTMLElement,
|
||||
isLinkInjectionEnabled: boolean
|
||||
): Promise<void> {
|
||||
await this.publishNotebookPaneAdapter.open(name, getFullName(), content, parentDomElement, isLinkInjectionEnabled);
|
||||
}
|
||||
|
||||
public openCopyNotebookPane(name: string, content: string): void {
|
||||
this.copyNotebookPaneAdapter.open(name, content);
|
||||
}
|
||||
|
||||
// Octokit's error handler uses any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private onGitHubClientError = (error: any): void => {
|
||||
Logger.logError(getErrorMessage(error), "NotebookManager/onGitHubClientError");
|
||||
|
||||
if (error.status === HttpStatusCodes.Unauthorized) {
|
||||
this.gitHubOAuthService.resetToken();
|
||||
|
||||
this.params.container.showOkCancelModalDialog(
|
||||
undefined,
|
||||
"Cosmos DB cannot access your Github account anymore. Please connect to GitHub again.",
|
||||
"Connect to GitHub",
|
||||
() => this.gitHubReposPane.open(),
|
||||
"Cancel",
|
||||
undefined
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private promptForCommitMsg = (title: string, primaryButtonLabel: string) => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
let commitMsg = "Committed from Azure Cosmos DB Notebooks";
|
||||
this.params.container.showOkCancelModalDialog(
|
||||
title || "Commit",
|
||||
undefined,
|
||||
primaryButtonLabel || "Commit",
|
||||
() => {
|
||||
TelemetryProcessor.trace(Action.NotebooksGitHubCommit, ActionModifiers.Mark, {
|
||||
databaseAccountName:
|
||||
this.params.container.databaseAccount() && this.params.container.databaseAccount().name,
|
||||
defaultExperience: this.params.container.defaultExperience && this.params.container.defaultExperience(),
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
});
|
||||
resolve(commitMsg);
|
||||
},
|
||||
"Cancel",
|
||||
() => reject(new Error("Commit dialog canceled")),
|
||||
undefined,
|
||||
{
|
||||
label: "Commit message",
|
||||
autoAdjustHeight: true,
|
||||
multiline: true,
|
||||
defaultValue: commitMsg,
|
||||
rows: 3,
|
||||
onChange: (_, newValue: string) => {
|
||||
commitMsg = newValue;
|
||||
this.params.dialogProps().primaryButtonDisabled = !commitMsg;
|
||||
this.params.dialogProps.valueHasMutated();
|
||||
},
|
||||
},
|
||||
!commitMsg
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,15 +62,15 @@ class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
||||
prompt: (props: { id: string; contentRef: string }) => this.renderPrompt(props.id, props.contentRef),
|
||||
editor: {
|
||||
monaco: (props: PassedEditorProps) =>
|
||||
this.props.hideInputs ? <></> : <MonacoEditor readOnly={true} {...props} editorType={"monaco"} />
|
||||
}
|
||||
this.props.hideInputs ? <></> : <MonacoEditor readOnly={true} {...props} editorType={"monaco"} />,
|
||||
},
|
||||
}}
|
||||
</CodeCell>
|
||||
),
|
||||
markdown: ({ id, contentRef }: { id: any; contentRef: ContentRef }) => (
|
||||
<MarkdownCell id={id} contentRef={contentRef} cell_type="markdown">
|
||||
{{
|
||||
editor: {}
|
||||
editor: {},
|
||||
}}
|
||||
</MarkdownCell>
|
||||
),
|
||||
@@ -79,11 +79,11 @@ class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
||||
{{
|
||||
editor: {
|
||||
monaco: (props: PassedEditorProps) =>
|
||||
this.props.hideInputs ? <></> : <MonacoEditor {...props} readOnly={true} editorType={"monaco"} />
|
||||
}
|
||||
this.props.hideInputs ? <></> : <MonacoEditor {...props} readOnly={true} editorType={"monaco"} />,
|
||||
},
|
||||
}}
|
||||
</RawCell>
|
||||
)
|
||||
),
|
||||
}}
|
||||
</Cells>
|
||||
<AzureTheme />
|
||||
@@ -99,10 +99,10 @@ const makeMapDispatchToProps = (initialDispatch: Dispatch, initialProps: Noteboo
|
||||
return dispatch(
|
||||
actions.addTransform({
|
||||
mediaType: transform.MIMETYPE,
|
||||
component: transform
|
||||
component: transform,
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
return mapDispatchToProps;
|
||||
|
||||
@@ -69,7 +69,7 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
hoveredCellId: undefined
|
||||
hoveredCellId: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -103,14 +103,14 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
<CodeCell id={id} contentRef={contentRef} cell_type="code">
|
||||
{{
|
||||
editor: {
|
||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />
|
||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />,
|
||||
},
|
||||
prompt: ({ id, contentRef }: { id: CellId; contentRef: ContentRef }) => (
|
||||
<Prompt id={id} contentRef={contentRef} isHovered={false}>
|
||||
{promptContent}
|
||||
</Prompt>
|
||||
),
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />,
|
||||
}}
|
||||
</CodeCell>
|
||||
),
|
||||
@@ -122,9 +122,9 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
<MarkdownCell id={id} contentRef={contentRef} cell_type="markdown">
|
||||
{{
|
||||
editor: {
|
||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />
|
||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />,
|
||||
},
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />,
|
||||
}}
|
||||
</MarkdownCell>
|
||||
),
|
||||
@@ -137,12 +137,12 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
<RawCell id={id} contentRef={contentRef} cell_type="raw">
|
||||
{{
|
||||
editor: {
|
||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />
|
||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />,
|
||||
},
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />,
|
||||
}}
|
||||
</RawCell>
|
||||
)
|
||||
),
|
||||
}}
|
||||
</Cells>
|
||||
</KeyboardShortcuts>
|
||||
@@ -163,7 +163,7 @@ const makeMapDispatchToProps = (initialDispatch: Dispatch, initialProps: Noteboo
|
||||
return dispatch(
|
||||
actions.addTransform({
|
||||
mediaType: transform.MIMETYPE,
|
||||
component: transform
|
||||
component: transform,
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -171,10 +171,10 @@ const makeMapDispatchToProps = (initialDispatch: Dispatch, initialProps: Noteboo
|
||||
return dispatch(
|
||||
cdbActions.UpdateNotebookParentDomElt({
|
||||
contentRef,
|
||||
parentElt
|
||||
parentElt,
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
return mapDispatchToProps;
|
||||
|
||||
@@ -46,7 +46,7 @@ export class PromptPure extends React.Component<Props> {
|
||||
executionCount: this.props.executionCount,
|
||||
runCell: this.props.executeCell,
|
||||
stopCell: this.props.stopExecution,
|
||||
isHovered: this.props.isHovered
|
||||
isHovered: this.props.isHovered,
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
@@ -74,7 +74,7 @@ const makeMapStateToProps = (state: CdbAppState, ownProps: ComponentProps): ((st
|
||||
return {
|
||||
status,
|
||||
executionCount,
|
||||
isHovered
|
||||
isHovered,
|
||||
};
|
||||
};
|
||||
return mapStateToProps;
|
||||
@@ -89,11 +89,11 @@ const mapDispatchToProps = (
|
||||
dispatch(
|
||||
cdbActions.traceNotebookTelemetry({
|
||||
action: Action.ExecuteCellPromptBtn,
|
||||
actionModifier: ActionModifiers.Mark
|
||||
actionModifier: ActionModifiers.Mark,
|
||||
})
|
||||
);
|
||||
},
|
||||
stopExecution: () => dispatch(actions.interruptKernel({}))
|
||||
stopExecution: () => dispatch(actions.interruptKernel({})),
|
||||
});
|
||||
|
||||
export default connect(makeMapStateToProps, mapDispatchToProps)(PromptPure);
|
||||
|
||||
@@ -26,7 +26,7 @@ describe("StatusBar", () => {
|
||||
{
|
||||
lastSaved,
|
||||
kernelSpecDisplayName: "javascript",
|
||||
kernelStatus: "kernelStatus"
|
||||
kernelStatus: "kernelStatus",
|
||||
},
|
||||
null,
|
||||
null
|
||||
@@ -45,7 +45,7 @@ describe("StatusBar", () => {
|
||||
{
|
||||
lastSaved: new Date(),
|
||||
kernelSpecDisplayName: "python3",
|
||||
kernelStatus: "kernelStatus"
|
||||
kernelStatus: "kernelStatus",
|
||||
},
|
||||
null,
|
||||
null
|
||||
|
||||
@@ -90,7 +90,7 @@ const makeMapStateToProps = (initialState: AppState, initialProps: InitialProps)
|
||||
return {
|
||||
kernelStatus: NOT_CONNECTED,
|
||||
kernelSpecDisplayName: "no kernel",
|
||||
lastSaved: null
|
||||
lastSaved: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ const makeMapStateToProps = (initialState: AppState, initialProps: InitialProps)
|
||||
return {
|
||||
kernelSpecDisplayName,
|
||||
kernelStatus,
|
||||
lastSaved
|
||||
lastSaved,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { IconButton } from "office-ui-fabric-react/lib/Button";
|
||||
import {
|
||||
DirectionalHint,
|
||||
IContextualMenuItem,
|
||||
ContextualMenuItemType
|
||||
ContextualMenuItemType,
|
||||
} from "office-ui-fabric-react/lib/ContextualMenu";
|
||||
import { actions, AppState, DocumentRecordProps } from "@nteract/core";
|
||||
import { CellToolbarContext } from "@nteract/stateful-components";
|
||||
@@ -54,7 +54,7 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.executeCell();
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksExecuteCellFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Clear Outputs",
|
||||
@@ -62,19 +62,19 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.clearOutputs();
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksClearOutputsFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Divider",
|
||||
itemType: ContextualMenuItemType.Divider
|
||||
}
|
||||
itemType: ContextualMenuItemType.Divider,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
items = items.concat([
|
||||
{
|
||||
key: "Divider2",
|
||||
itemType: ContextualMenuItemType.Divider
|
||||
itemType: ContextualMenuItemType.Divider,
|
||||
},
|
||||
{
|
||||
key: "Insert Code Cell Above",
|
||||
@@ -82,7 +82,7 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.insertCodeCellAbove();
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksInsertCodeCellAboveFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Insert Code Cell Below",
|
||||
@@ -90,7 +90,7 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.insertCodeCellBelow();
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksInsertCodeCellBelowFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Insert Text Cell Above",
|
||||
@@ -98,7 +98,7 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.insertTextCellAbove();
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksInsertTextCellAboveFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Insert Text Cell Below",
|
||||
@@ -106,12 +106,12 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.insertTextCellBelow();
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksInsertTextCellBelowFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Divider3",
|
||||
itemType: ContextualMenuItemType.Divider
|
||||
}
|
||||
itemType: ContextualMenuItemType.Divider,
|
||||
},
|
||||
]);
|
||||
|
||||
const moveItems: IContextualMenuItem[] = [];
|
||||
@@ -122,7 +122,7 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.moveCell(this.props.cellIdAbove, true);
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksMoveCellUpFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -133,14 +133,14 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.moveCell(this.props.cellIdBelow, false);
|
||||
this.props.traceNotebookTelemetry(Action.NotebooksMoveCellDownFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (moveItems.length > 0) {
|
||||
moveItems.push({
|
||||
key: "Divider4",
|
||||
itemType: ContextualMenuItemType.Divider
|
||||
itemType: ContextualMenuItemType.Divider,
|
||||
});
|
||||
items = items.concat(moveItems);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
onClick: () => {
|
||||
this.props.deleteCell();
|
||||
this.props.traceNotebookTelemetry(Action.DeleteCellFromMenu, ActionModifiers.Mark);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const menuItemLabel = "More";
|
||||
@@ -162,12 +162,12 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
ariaLabel={menuItemLabel}
|
||||
menuIconProps={{
|
||||
iconName: menuItemLabel,
|
||||
styles: { root: { fontSize: "18px", fontWeight: "bold" } }
|
||||
styles: { root: { fontSize: "18px", fontWeight: "bold" } },
|
||||
}}
|
||||
menuProps={{
|
||||
isBeakVisible: false,
|
||||
directionalHint: DirectionalHint.bottomRightEdge,
|
||||
items
|
||||
items,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -188,7 +188,7 @@ const mapDispatchToProps = (
|
||||
clearOutputs: () => dispatch(actions.clearOutputs({ id, contentRef })),
|
||||
deleteCell: () => dispatch(actions.deleteCell({ id, contentRef })),
|
||||
traceNotebookTelemetry: (action: Action, actionModifier?: string, data?: any) =>
|
||||
dispatch(cdbActions.traceNotebookTelemetry({ action, actionModifier, data }))
|
||||
dispatch(cdbActions.traceNotebookTelemetry({ action, actionModifier, data })),
|
||||
});
|
||||
|
||||
const makeMapStateToProps = (state: AppState, ownProps: ComponentProps): ((state: AppState) => StateProps) => {
|
||||
@@ -204,7 +204,7 @@ const makeMapStateToProps = (state: AppState, ownProps: ComponentProps): ((state
|
||||
return {
|
||||
cellType,
|
||||
cellIdAbove,
|
||||
cellIdBelow
|
||||
cellIdBelow,
|
||||
};
|
||||
};
|
||||
return mapStateToProps;
|
||||
|
||||
@@ -193,12 +193,12 @@ const mapStateToProps = (state: AppState, ownProps: ComponentProps) => {
|
||||
|
||||
if (model && model.type === "notebook") {
|
||||
const cellOrder = selectors.notebook.cellOrder(model);
|
||||
const cellIndex = cellOrder.findIndex(cellId => cellId === id);
|
||||
const cellIndex = cellOrder.findIndex((cellId) => cellId === id);
|
||||
isFirstCell = cellIndex === 0;
|
||||
}
|
||||
|
||||
return {
|
||||
isFirstCell
|
||||
isFirstCell,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -208,7 +208,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
|
||||
createCellAppend: (payload: { cellType: CellType; contentRef: ContentRef }) =>
|
||||
dispatch(actions.createCellAppend(payload)),
|
||||
createCellBelow: (payload: { cellType: CellType; id?: string; source: string; contentRef: ContentRef }) =>
|
||||
dispatch(actions.createCellBelow(payload))
|
||||
dispatch(actions.createCellBelow(payload)),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(CellCreator);
|
||||
|
||||
@@ -36,7 +36,7 @@ const makeMapStateToProps = (state: AppState, ownProps: ComponentProps): ((state
|
||||
const cellIndex = cellOrder.indexOf(ownProps.id);
|
||||
|
||||
return {
|
||||
cellIndex
|
||||
cellIndex,
|
||||
};
|
||||
};
|
||||
return mapStateToProps;
|
||||
|
||||
@@ -34,7 +34,7 @@ const mapDispatchToProps = (
|
||||
{ id, contentRef }: { id: string; contentRef: ContentRef }
|
||||
): DispatchProps => ({
|
||||
hover: () => dispatch(actions.setHoveredCell({ cellId: id })),
|
||||
unHover: () => dispatch(actions.setHoveredCell({ cellId: undefined }))
|
||||
unHover: () => dispatch(actions.setHoveredCell({ cellId: undefined })),
|
||||
});
|
||||
|
||||
export default connect(undefined, mapDispatchToProps)(HoverableCell);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
DragSourceMonitor,
|
||||
DropTarget,
|
||||
DropTargetConnector,
|
||||
DropTargetMonitor
|
||||
DropTargetMonitor,
|
||||
} from "react-dnd";
|
||||
|
||||
import { connect } from "react-redux";
|
||||
@@ -43,7 +43,7 @@ const cellDragPreviewImage = [
|
||||
"s46mRlWqQiudxebVV3gAj7C9hXsmgZeztnfe/91YODEr3IoF/JY/sE2gbGaVLci3",
|
||||
"hh0tRtWNvsm16JmNcOs6N9dW72LP7yOtWbEhjAUkZ+icoJ5HbE6+NSxMjKWe6cKb",
|
||||
"GkUWgMwiFbXSlRpFkXelUlF4F70rVd7Bd4oZ/LL8xiDmtPV2Nwyf2zOlTfHERY7i",
|
||||
"Haa1+w2+iFqx0aIgvgAAAABJRU5ErkJggg=="
|
||||
"Haa1+w2+iFqx0aIgvgAAAABJRU5ErkJggg==",
|
||||
].join("");
|
||||
|
||||
interface Props {
|
||||
@@ -72,13 +72,13 @@ interface State {
|
||||
const cellSource = {
|
||||
beginDrag(props: Props) {
|
||||
return {
|
||||
id: props.id
|
||||
id: props.id,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const DragHandle = styled.div.attrs({
|
||||
role: "presentation"
|
||||
role: "presentation",
|
||||
})`
|
||||
position: absolute;
|
||||
z-index: 200;
|
||||
@@ -93,12 +93,12 @@ interface DragAreaProps {
|
||||
hoverUpperHalf: boolean;
|
||||
}
|
||||
|
||||
const DragArea = styled.div.attrs<DragAreaProps>(props => ({
|
||||
const DragArea = styled.div.attrs<DragAreaProps>((props) => ({
|
||||
style: {
|
||||
opacity: props.isDragging ? 0.25 : 1,
|
||||
borderTop: props.isOver && props.hoverUpperHalf ? "3px lightgray solid" : "3px transparent solid",
|
||||
borderBottom: props.isOver && !props.hoverUpperHalf ? "3px lightgray solid" : "3px transparent solid"
|
||||
}
|
||||
borderBottom: props.isOver && !props.hoverUpperHalf ? "3px lightgray solid" : "3px transparent solid",
|
||||
},
|
||||
}))`
|
||||
padding: 10px;
|
||||
margin-top: -15px;
|
||||
@@ -128,7 +128,7 @@ export const cellTarget = {
|
||||
id: monitor.getItem().id,
|
||||
destinationId: props.id,
|
||||
above: hoverUpperHalf,
|
||||
contentRef: props.contentRef
|
||||
contentRef: props.contentRef,
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -136,10 +136,10 @@ export const cellTarget = {
|
||||
hover(props: Props, monitor: DropTargetMonitor, component: any): void {
|
||||
if (monitor) {
|
||||
component.setState({
|
||||
hoverUpperHalf: isDragUpper(props, monitor, component.el)
|
||||
hoverUpperHalf: isDragUpper(props, monitor, component.el),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function collectSource(
|
||||
@@ -153,7 +153,7 @@ function collectSource(
|
||||
return {
|
||||
connectDragSource: connect.dragSource(),
|
||||
isDragging: monitor.isDragging(),
|
||||
connectDragPreview: connect.dragPreview()
|
||||
connectDragPreview: connect.dragPreview(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ function collectTarget(
|
||||
} {
|
||||
return {
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
isOver: monitor.isOver()
|
||||
isOver: monitor.isOver(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ export class DraggableCellView extends React.Component<Props & DnDSourceProps &
|
||||
el?: HTMLDivElement | null;
|
||||
|
||||
state = {
|
||||
hoverUpperHalf: true
|
||||
hoverUpperHalf: true,
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
@@ -201,7 +201,7 @@ export class DraggableCellView extends React.Component<Props & DnDSourceProps &
|
||||
isDragging={this.props.isDragging}
|
||||
hoverUpperHalf={this.state.hoverUpperHalf}
|
||||
isOver={this.props.isOver}
|
||||
ref={el => {
|
||||
ref={(el) => {
|
||||
this.el = el;
|
||||
}}
|
||||
>
|
||||
@@ -226,7 +226,7 @@ const target = DropTarget<Props, DnDTargetProps>("CELL", cellTarget, collectTarg
|
||||
export const makeMapDispatchToProps = (initialDispatch: Dispatch) => {
|
||||
const mapDispatchToProps = (dispatch: Dispatch) => ({
|
||||
moveCell: (payload: actions.MoveCell["payload"]) => dispatch(actions.moveCell(payload)),
|
||||
focusCell: (payload: actions.FocusCell["payload"]) => dispatch(actions.focusCell(payload))
|
||||
focusCell: (payload: actions.FocusCell["payload"]) => dispatch(actions.focusCell(payload)),
|
||||
});
|
||||
return mapDispatchToProps;
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@ export class HijackScroll extends React.Component<Props> {
|
||||
<div
|
||||
onClick={this.props.selectCell}
|
||||
role="presentation"
|
||||
ref={el => {
|
||||
ref={(el) => {
|
||||
this.el = el;
|
||||
}}
|
||||
>
|
||||
@@ -81,7 +81,7 @@ const makeMapStateToProps = (initialState: AppState, ownProps: ComponentProps) =
|
||||
}
|
||||
|
||||
return {
|
||||
focused
|
||||
focused,
|
||||
};
|
||||
};
|
||||
return mapStateToProps;
|
||||
@@ -89,7 +89,7 @@ const makeMapStateToProps = (initialState: AppState, ownProps: ComponentProps) =
|
||||
|
||||
const makeMapDispatchToProps = (initialDispatch: Dispatch, ownProps: ComponentProps) => {
|
||||
const mapDispatchToProps = (dispatch: Dispatch) => ({
|
||||
selectCell: () => dispatch(actions.focusCell({ id: ownProps.id, contentRef: ownProps.contentRef }))
|
||||
selectCell: () => dispatch(actions.focusCell({ id: ownProps.id, contentRef: ownProps.contentRef })),
|
||||
});
|
||||
return mapDispatchToProps;
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ export class KeyboardShortcuts extends React.Component<Props> {
|
||||
contentRef,
|
||||
cellOrder,
|
||||
focusedCell,
|
||||
cellMap
|
||||
cellMap,
|
||||
} = this.props;
|
||||
|
||||
let ctrlKeyPressed = e.ctrlKey;
|
||||
@@ -90,7 +90,7 @@ export class KeyboardShortcuts extends React.Component<Props> {
|
||||
focusNextCell({
|
||||
id: undefined,
|
||||
createCellIfUndefined: true,
|
||||
contentRef
|
||||
contentRef,
|
||||
});
|
||||
|
||||
/** Only focus the next editor if it is a code cell or a cell
|
||||
@@ -125,7 +125,7 @@ export const makeMapStateToProps = (state: AppState, ownProps: ComponentProps) =
|
||||
return {
|
||||
cellOrder,
|
||||
cellMap,
|
||||
focusedCell
|
||||
focusedCell,
|
||||
};
|
||||
};
|
||||
return mapStateToProps;
|
||||
@@ -136,7 +136,7 @@ export const mapDispatchToProps = (dispatch: Dispatch) => ({
|
||||
focusNextCell: (payload: { id?: CellId; createCellIfUndefined: boolean; contentRef: ContentRef }) =>
|
||||
dispatch(actions.focusNextCell(payload)),
|
||||
focusNextCellEditor: (payload: { id?: CellId; contentRef: ContentRef }) =>
|
||||
dispatch(actions.focusNextCellEditor(payload))
|
||||
dispatch(actions.focusNextCellEditor(payload)),
|
||||
});
|
||||
|
||||
export default connect(makeMapStateToProps, mapDispatchToProps)(KeyboardShortcuts);
|
||||
|
||||
@@ -1,137 +1,137 @@
|
||||
import { NotebookUtil } from "./NotebookUtil";
|
||||
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
||||
import {
|
||||
ImmutableNotebook,
|
||||
MediaBundle,
|
||||
CodeCellParams,
|
||||
MarkdownCellParams,
|
||||
makeCodeCell,
|
||||
makeMarkdownCell,
|
||||
makeNotebookRecord
|
||||
} from "@nteract/commutable";
|
||||
import { List, Map } from "immutable";
|
||||
|
||||
const fileName = "file";
|
||||
const notebookName = "file.ipynb";
|
||||
const folderPath = "folder";
|
||||
const filePath = `${folderPath}/${fileName}`;
|
||||
const notebookPath = `${folderPath}/${notebookName}`;
|
||||
const gitHubFolderUri = GitHubUtils.toContentUri("owner", "repo", "branch", folderPath);
|
||||
const gitHubFileUri = GitHubUtils.toContentUri("owner", "repo", "branch", filePath);
|
||||
const gitHubNotebookUri = GitHubUtils.toContentUri("owner", "repo", "branch", notebookPath);
|
||||
const notebookRecord = makeNotebookRecord({
|
||||
cellOrder: List.of("0", "1", "2", "3"),
|
||||
cellMap: Map({
|
||||
"0": makeMarkdownCell({
|
||||
cell_type: "markdown",
|
||||
source: "abc",
|
||||
metadata: undefined
|
||||
} as MarkdownCellParams),
|
||||
"1": makeCodeCell({
|
||||
cell_type: "code",
|
||||
execution_count: undefined,
|
||||
metadata: undefined,
|
||||
source: "print(5)",
|
||||
outputs: List.of({
|
||||
name: "stdout",
|
||||
output_type: "stream",
|
||||
text: "5"
|
||||
})
|
||||
} as CodeCellParams),
|
||||
"2": makeCodeCell({
|
||||
cell_type: "code",
|
||||
execution_count: undefined,
|
||||
metadata: undefined,
|
||||
source: 'display(HTML("<h1>Sample html</h1>"))',
|
||||
outputs: List.of({
|
||||
data: Object.freeze({
|
||||
"text/html": "<h1>Sample output</h1>",
|
||||
"text/plain": "<IPython.core.display.HTML object>"
|
||||
} as MediaBundle),
|
||||
output_type: "display_data",
|
||||
metadata: undefined
|
||||
})
|
||||
} as CodeCellParams),
|
||||
"3": makeCodeCell({
|
||||
cell_type: "code",
|
||||
execution_count: undefined,
|
||||
metadata: undefined,
|
||||
source: 'print("hello world")',
|
||||
outputs: List.of({
|
||||
name: "stdout",
|
||||
output_type: "stream",
|
||||
text: "hello world"
|
||||
})
|
||||
} as CodeCellParams)
|
||||
}),
|
||||
nbformat_minor: 2,
|
||||
nbformat: 2,
|
||||
metadata: undefined
|
||||
});
|
||||
|
||||
describe("NotebookUtil", () => {
|
||||
describe("isNotebookFile", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.isNotebookFile(filePath)).toBeFalsy();
|
||||
expect(NotebookUtil.isNotebookFile(notebookPath)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.isNotebookFile(gitHubFileUri)).toBeFalsy();
|
||||
expect(NotebookUtil.isNotebookFile(gitHubNotebookUri)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("getFilePath", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.getFilePath(folderPath, fileName)).toEqual(filePath);
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.getFilePath(gitHubFolderUri, fileName)).toEqual(gitHubFileUri);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getParentPath", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.getParentPath(filePath)).toEqual(folderPath);
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.getParentPath(gitHubFileUri)).toEqual(gitHubFolderUri);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getName", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.getName(filePath)).toEqual(fileName);
|
||||
expect(NotebookUtil.getName(notebookPath)).toEqual(notebookName);
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.getName(gitHubFileUri)).toEqual(fileName);
|
||||
expect(NotebookUtil.getName(gitHubNotebookUri)).toEqual(notebookName);
|
||||
});
|
||||
});
|
||||
|
||||
describe("replaceName", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.replaceName(filePath, "newName")).toEqual(filePath.replace(fileName, "newName"));
|
||||
expect(NotebookUtil.replaceName(notebookPath, "newName")).toEqual(notebookPath.replace(notebookName, "newName"));
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.replaceName(gitHubFileUri, "newName")).toEqual(gitHubFileUri.replace(fileName, "newName"));
|
||||
expect(NotebookUtil.replaceName(gitHubNotebookUri, "newName")).toEqual(
|
||||
gitHubNotebookUri.replace(notebookName, "newName")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findFirstCodeCellWithDisplay", () => {
|
||||
it("works for Notebook file", () => {
|
||||
const notebookObject = notebookRecord as ImmutableNotebook;
|
||||
expect(NotebookUtil.findFirstCodeCellWithDisplay(notebookObject)).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
import { NotebookUtil } from "./NotebookUtil";
|
||||
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
||||
import {
|
||||
ImmutableNotebook,
|
||||
MediaBundle,
|
||||
CodeCellParams,
|
||||
MarkdownCellParams,
|
||||
makeCodeCell,
|
||||
makeMarkdownCell,
|
||||
makeNotebookRecord,
|
||||
} from "@nteract/commutable";
|
||||
import { List, Map } from "immutable";
|
||||
|
||||
const fileName = "file";
|
||||
const notebookName = "file.ipynb";
|
||||
const folderPath = "folder";
|
||||
const filePath = `${folderPath}/${fileName}`;
|
||||
const notebookPath = `${folderPath}/${notebookName}`;
|
||||
const gitHubFolderUri = GitHubUtils.toContentUri("owner", "repo", "branch", folderPath);
|
||||
const gitHubFileUri = GitHubUtils.toContentUri("owner", "repo", "branch", filePath);
|
||||
const gitHubNotebookUri = GitHubUtils.toContentUri("owner", "repo", "branch", notebookPath);
|
||||
const notebookRecord = makeNotebookRecord({
|
||||
cellOrder: List.of("0", "1", "2", "3"),
|
||||
cellMap: Map({
|
||||
"0": makeMarkdownCell({
|
||||
cell_type: "markdown",
|
||||
source: "abc",
|
||||
metadata: undefined,
|
||||
} as MarkdownCellParams),
|
||||
"1": makeCodeCell({
|
||||
cell_type: "code",
|
||||
execution_count: undefined,
|
||||
metadata: undefined,
|
||||
source: "print(5)",
|
||||
outputs: List.of({
|
||||
name: "stdout",
|
||||
output_type: "stream",
|
||||
text: "5",
|
||||
}),
|
||||
} as CodeCellParams),
|
||||
"2": makeCodeCell({
|
||||
cell_type: "code",
|
||||
execution_count: undefined,
|
||||
metadata: undefined,
|
||||
source: 'display(HTML("<h1>Sample html</h1>"))',
|
||||
outputs: List.of({
|
||||
data: Object.freeze({
|
||||
"text/html": "<h1>Sample output</h1>",
|
||||
"text/plain": "<IPython.core.display.HTML object>",
|
||||
} as MediaBundle),
|
||||
output_type: "display_data",
|
||||
metadata: undefined,
|
||||
}),
|
||||
} as CodeCellParams),
|
||||
"3": makeCodeCell({
|
||||
cell_type: "code",
|
||||
execution_count: undefined,
|
||||
metadata: undefined,
|
||||
source: 'print("hello world")',
|
||||
outputs: List.of({
|
||||
name: "stdout",
|
||||
output_type: "stream",
|
||||
text: "hello world",
|
||||
}),
|
||||
} as CodeCellParams),
|
||||
}),
|
||||
nbformat_minor: 2,
|
||||
nbformat: 2,
|
||||
metadata: undefined,
|
||||
});
|
||||
|
||||
describe("NotebookUtil", () => {
|
||||
describe("isNotebookFile", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.isNotebookFile(filePath)).toBeFalsy();
|
||||
expect(NotebookUtil.isNotebookFile(notebookPath)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.isNotebookFile(gitHubFileUri)).toBeFalsy();
|
||||
expect(NotebookUtil.isNotebookFile(gitHubNotebookUri)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("getFilePath", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.getFilePath(folderPath, fileName)).toEqual(filePath);
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.getFilePath(gitHubFolderUri, fileName)).toEqual(gitHubFileUri);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getParentPath", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.getParentPath(filePath)).toEqual(folderPath);
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.getParentPath(gitHubFileUri)).toEqual(gitHubFolderUri);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getName", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.getName(filePath)).toEqual(fileName);
|
||||
expect(NotebookUtil.getName(notebookPath)).toEqual(notebookName);
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.getName(gitHubFileUri)).toEqual(fileName);
|
||||
expect(NotebookUtil.getName(gitHubNotebookUri)).toEqual(notebookName);
|
||||
});
|
||||
});
|
||||
|
||||
describe("replaceName", () => {
|
||||
it("works for jupyter file paths", () => {
|
||||
expect(NotebookUtil.replaceName(filePath, "newName")).toEqual(filePath.replace(fileName, "newName"));
|
||||
expect(NotebookUtil.replaceName(notebookPath, "newName")).toEqual(notebookPath.replace(notebookName, "newName"));
|
||||
});
|
||||
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.replaceName(gitHubFileUri, "newName")).toEqual(gitHubFileUri.replace(fileName, "newName"));
|
||||
expect(NotebookUtil.replaceName(gitHubNotebookUri, "newName")).toEqual(
|
||||
gitHubNotebookUri.replace(notebookName, "newName")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findFirstCodeCellWithDisplay", () => {
|
||||
it("works for Notebook file", () => {
|
||||
const notebookObject = notebookRecord as ImmutableNotebook;
|
||||
expect(NotebookUtil.findFirstCodeCellWithDisplay(notebookObject)).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export class NotebookUtil {
|
||||
name,
|
||||
path,
|
||||
type: NotebookUtil.getType(type),
|
||||
timestamp: NotebookUtil.getCurrentTimestamp()
|
||||
timestamp: NotebookUtil.getCurrentTimestamp(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export class NotebookUtil {
|
||||
|
||||
return {
|
||||
cwd,
|
||||
kernelSpecName
|
||||
kernelSpecName,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ export class NotebookUtil {
|
||||
const cell = notebookObject.cellMap.get(cellId);
|
||||
if (cell?.cell_type === "code") {
|
||||
const displayOutput = (cell as ImmutableCodeCell)?.outputs?.find(
|
||||
output => output.output_type === "display_data" || output.output_type === "execute_result"
|
||||
(output) => output.output_type === "display_data" || output.output_type === "execute_result"
|
||||
);
|
||||
if (displayOutput) {
|
||||
return codeCellIndex;
|
||||
|
||||
@@ -9,31 +9,31 @@ describe("auto start kernel", () => {
|
||||
(configureStore as jest.Mock).mockReturnValue({
|
||||
dispatch: () => {
|
||||
/* noop */
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
defineConfigOption({
|
||||
label: "editorType",
|
||||
key: "editorType",
|
||||
defaultValue: "foo"
|
||||
defaultValue: "foo",
|
||||
});
|
||||
|
||||
defineConfigOption({
|
||||
label: "autoSaveInterval",
|
||||
key: "autoSaveInterval",
|
||||
defaultValue: 1234
|
||||
defaultValue: 1234,
|
||||
});
|
||||
|
||||
[true, false].forEach(isReadOnly => {
|
||||
[true, false].forEach((isReadOnly) => {
|
||||
new NotebookClientV2({
|
||||
connectionInfo: {
|
||||
authToken: "autToken",
|
||||
notebookServerEndpoint: "notebookServerEndpoint"
|
||||
notebookServerEndpoint: "notebookServerEndpoint",
|
||||
},
|
||||
databaseAccountName: undefined,
|
||||
defaultExperience: undefined,
|
||||
isReadOnly,
|
||||
contentProvider: undefined
|
||||
contentProvider: undefined,
|
||||
});
|
||||
|
||||
expect(configureStore).toHaveBeenCalledWith(
|
||||
|
||||
Reference in New Issue
Block a user