mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-03-13 05:15:30 +00:00
199 lines
6.4 KiB
TypeScript
199 lines
6.4 KiB
TypeScript
import ko from "knockout";
|
|
import * as React from "react";
|
|
import { ReactAdapter } from "../../Bindings/ReactBindingHandler";
|
|
import * as Logger from "../../Common/Logger";
|
|
import { JunoClient, IPinnedRepo } from "../../Juno/JunoClient";
|
|
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
|
|
import Explorer from "../Explorer";
|
|
import { GenericRightPaneComponent, GenericRightPaneProps } from "./GenericRightPaneComponent";
|
|
import { CopyNotebookPaneComponent, CopyNotebookPaneProps } from "./CopyNotebookPaneComponent";
|
|
import { IDropdownOption } from "office-ui-fabric-react";
|
|
import { GitHubOAuthService } from "../../GitHub/GitHubOAuthService";
|
|
import { HttpStatusCodes } from "../../Common/Constants";
|
|
import * as GitHubUtils from "../../Utils/GitHubUtils";
|
|
import { NotebookContentItemType, NotebookContentItem } from "../Notebook/NotebookContentItem";
|
|
import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter";
|
|
|
|
interface Location {
|
|
type: "MyNotebooks" | "GitHub";
|
|
|
|
// GitHub
|
|
owner?: string;
|
|
repo?: string;
|
|
branch?: string;
|
|
}
|
|
|
|
export class CopyNotebookPaneAdapter implements ReactAdapter {
|
|
private static readonly BranchNameWhiteSpace = " ";
|
|
|
|
parameters: ko.Observable<number>;
|
|
private isOpened: boolean;
|
|
private isExecuting: boolean;
|
|
private formError: string;
|
|
private formErrorDetail: string;
|
|
private name: string;
|
|
private content: string;
|
|
private pinnedRepos: IPinnedRepo[];
|
|
private selectedLocation: Location;
|
|
|
|
constructor(
|
|
private container: Explorer,
|
|
private junoClient: JunoClient,
|
|
private gitHubOAuthService: GitHubOAuthService
|
|
) {
|
|
this.parameters = ko.observable(Date.now());
|
|
this.reset();
|
|
this.triggerRender();
|
|
}
|
|
|
|
public renderComponent(): JSX.Element {
|
|
if (!this.isOpened) {
|
|
return undefined;
|
|
}
|
|
|
|
const genericPaneProps: GenericRightPaneProps = {
|
|
container: this.container,
|
|
formError: this.formError,
|
|
formErrorDetail: this.formErrorDetail,
|
|
id: "copynotebookpane",
|
|
isExecuting: this.isExecuting,
|
|
title: "Copy notebook",
|
|
submitButtonText: "OK",
|
|
onClose: () => this.close(),
|
|
onSubmit: () => this.submit()
|
|
};
|
|
|
|
const copyNotebookPaneProps: CopyNotebookPaneProps = {
|
|
name: this.name,
|
|
pinnedRepos: this.pinnedRepos,
|
|
onDropDownChange: this.onDropDownChange
|
|
};
|
|
|
|
return (
|
|
<GenericRightPaneComponent {...genericPaneProps}>
|
|
<CopyNotebookPaneComponent {...copyNotebookPaneProps} />
|
|
</GenericRightPaneComponent>
|
|
);
|
|
}
|
|
|
|
public triggerRender(): void {
|
|
window.requestAnimationFrame(() => this.parameters(Date.now()));
|
|
}
|
|
|
|
public async open(name: string, content: string): Promise<void> {
|
|
this.name = name;
|
|
this.content = content;
|
|
|
|
this.isOpened = true;
|
|
this.triggerRender();
|
|
|
|
if (this.gitHubOAuthService.isLoggedIn()) {
|
|
const response = await this.junoClient.getPinnedRepos(this.gitHubOAuthService.getTokenObservable()()?.scope);
|
|
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
|
const message = `Received HTTP ${response.status} when fetching pinned repos`;
|
|
Logger.logError(message, "CopyNotebookPaneAdapter/submit");
|
|
NotificationConsoleUtils.logConsoleError(message);
|
|
}
|
|
|
|
if (response.data?.length > 0) {
|
|
this.pinnedRepos = response.data;
|
|
this.triggerRender();
|
|
}
|
|
}
|
|
}
|
|
|
|
public close(): void {
|
|
this.reset();
|
|
this.triggerRender();
|
|
}
|
|
|
|
public async submit(): Promise<void> {
|
|
let destination: string = this.selectedLocation?.type;
|
|
let clearMessage: () => void;
|
|
this.isExecuting = true;
|
|
this.triggerRender();
|
|
|
|
try {
|
|
if (!this.selectedLocation) {
|
|
throw new Error(`No location selected`);
|
|
}
|
|
|
|
if (this.selectedLocation.type === "GitHub") {
|
|
destination = `${destination} - ${GitHubUtils.toRepoFullName(
|
|
this.selectedLocation.owner,
|
|
this.selectedLocation.repo
|
|
)} - ${this.selectedLocation.branch}`;
|
|
}
|
|
|
|
clearMessage = NotificationConsoleUtils.logConsoleProgress(`Copying ${this.name} to ${destination}`);
|
|
|
|
const notebookContentItem = await this.copyNotebook(this.selectedLocation);
|
|
if (!notebookContentItem) {
|
|
throw new Error(`Failed to upload ${this.name}`);
|
|
}
|
|
|
|
NotificationConsoleUtils.logConsoleInfo(`Successfully copied ${this.name} to ${destination}`);
|
|
} catch (error) {
|
|
this.formError = `Failed to copy ${this.name} to ${destination}`;
|
|
this.formErrorDetail = `${error}`;
|
|
|
|
const message = `${this.formError}: ${this.formErrorDetail}`;
|
|
Logger.logError(message, "CopyNotebookPaneAdapter/submit");
|
|
NotificationConsoleUtils.logConsoleError(message);
|
|
return;
|
|
} finally {
|
|
clearMessage && clearMessage();
|
|
this.isExecuting = false;
|
|
this.triggerRender();
|
|
}
|
|
|
|
this.close();
|
|
}
|
|
|
|
private copyNotebook = async (location: Location): Promise<NotebookContentItem> => {
|
|
let parent: NotebookContentItem;
|
|
switch (location.type) {
|
|
case "MyNotebooks":
|
|
parent = {
|
|
name: ResourceTreeAdapter.MyNotebooksTitle,
|
|
path: this.container.getNotebookBasePath(),
|
|
type: NotebookContentItemType.Directory
|
|
};
|
|
break;
|
|
|
|
case "GitHub":
|
|
parent = {
|
|
name: ResourceTreeAdapter.GitHubReposTitle,
|
|
path: GitHubUtils.toContentUri(
|
|
this.selectedLocation.owner,
|
|
this.selectedLocation.repo,
|
|
this.selectedLocation.branch,
|
|
""
|
|
),
|
|
type: NotebookContentItemType.Directory
|
|
};
|
|
break;
|
|
|
|
default:
|
|
throw new Error(`Unsupported location type ${location.type}`);
|
|
}
|
|
|
|
return this.container.uploadFile(this.name, this.content, parent);
|
|
};
|
|
|
|
private onDropDownChange = (_: React.FormEvent<HTMLDivElement>, option?: IDropdownOption): void => {
|
|
this.selectedLocation = option?.data;
|
|
};
|
|
|
|
private reset = (): void => {
|
|
this.isOpened = false;
|
|
this.isExecuting = false;
|
|
this.formError = undefined;
|
|
this.formErrorDetail = undefined;
|
|
this.name = undefined;
|
|
this.content = undefined;
|
|
this.pinnedRepos = undefined;
|
|
this.selectedLocation = undefined;
|
|
};
|
|
}
|