Files
cosmos-explorer/src/Explorer/Controls/GitHub/AddRepoComponent.tsx
2021-10-28 17:08:34 +05:30

122 lines
3.9 KiB
TypeScript

import { DefaultButton, IButtonProps, ITextFieldProps, TextField } from "@fluentui/react";
import * as React from "react";
import * as Constants from "../../../Common/Constants";
import * as UrlUtility from "../../../Common/UrlUtility";
import { IGitHubRepo } from "../../../GitHub/GitHubClient";
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
import * as GitHubUtils from "../../../Utils/GitHubUtils";
import Explorer from "../../Explorer";
import { RepoListItem } from "./GitHubReposComponent";
import { ChildrenMargin } from "./GitHubStyleConstants";
export interface AddRepoComponentProps {
container: Explorer;
getRepo: (owner: string, repo: string) => Promise<IGitHubRepo>;
pinRepo: (item: RepoListItem) => void;
}
interface AddRepoComponentState {
textFieldValue: string;
textFieldErrorMessage: string;
}
export class AddRepoComponent extends React.Component<AddRepoComponentProps, AddRepoComponentState> {
private static readonly DescriptionText =
"Don't see what you're looking for? Add your repo/branch, or any public repo (read-access only) by entering the URL: ";
private static readonly ButtonText = "Add";
private static readonly TextFieldPlaceholder = "https://github.com/owner/repo/tree/branch";
private static readonly TextFieldErrorMessage = "Invalid url";
constructor(props: AddRepoComponentProps) {
super(props);
this.state = {
textFieldValue: "",
textFieldErrorMessage: undefined,
};
}
public render(): JSX.Element {
const textFieldProps: ITextFieldProps = {
placeholder: AddRepoComponent.TextFieldPlaceholder,
autoFocus: true,
value: this.state.textFieldValue,
errorMessage: this.state.textFieldErrorMessage,
onChange: this.onTextFieldChange,
};
const buttonProps: IButtonProps = {
text: AddRepoComponent.ButtonText,
ariaLabel: AddRepoComponent.ButtonText,
onClick: this.onAddRepoButtonClick,
};
return (
<>
<p style={{ marginBottom: ChildrenMargin }}>{AddRepoComponent.DescriptionText}</p>
<TextField {...textFieldProps} />
<DefaultButton style={{ marginTop: ChildrenMargin }} {...buttonProps} />
</>
);
}
private onTextFieldChange = (
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
newValue?: string
): void => {
this.setState({
textFieldValue: newValue || "",
textFieldErrorMessage: undefined,
});
};
private onAddRepoButtonClick = async (): Promise<void> => {
const startKey: number = TelemetryProcessor.traceStart(Action.NotebooksGitHubManualRepoAdd, {
dataExplorerArea: Constants.Areas.Notebook,
});
let enteredUrl = this.state.textFieldValue;
if (enteredUrl.indexOf("/tree/") === -1) {
enteredUrl = UrlUtility.createUri(enteredUrl, `tree/`);
}
const repoInfo = GitHubUtils.fromRepoUri(enteredUrl);
if (repoInfo) {
this.setState({
textFieldValue: "",
textFieldErrorMessage: undefined,
});
const repo = await this.props.getRepo(repoInfo.owner, repoInfo.repo);
if (repo) {
const item: RepoListItem = {
key: GitHubUtils.toRepoFullName(repo.owner, repo.name),
repo,
branches: repoInfo.branch ? [{ name: repoInfo.branch }] : [],
};
TelemetryProcessor.traceSuccess(
Action.NotebooksGitHubManualRepoAdd,
{
dataExplorerArea: Constants.Areas.Notebook,
},
startKey
);
return this.props.pinRepo(item);
}
}
this.setState({
textFieldErrorMessage: AddRepoComponent.TextFieldErrorMessage,
});
TelemetryProcessor.traceFailure(
Action.NotebooksGitHubManualRepoAdd,
{
dataExplorerArea: Constants.Areas.Notebook,
error: AddRepoComponent.TextFieldErrorMessage,
},
startKey
);
};
}