import { Dropdown, IDropdownProps, ITextFieldProps, Stack, Text, TextField } from "@fluentui/react"; import { ImmutableNotebook } from "@nteract/commutable"; import React, { FunctionComponent, useState } from "react"; import { GalleryCardComponent } from "../../Controls/NotebookGallery/Cards/GalleryCardComponent"; import * as FileSystemUtil from "../../Notebook/FileSystemUtil"; import { SnapshotRequest } from "../../Notebook/NotebookComponent/types"; import { NotebookUtil } from "../../Notebook/NotebookUtil"; import "./styled.less"; export interface PublishNotebookPaneProps { notebookName: string; notebookAuthor: string; notebookTags: string; notebookDescription: string; notebookCreatedDate: string; notebookObject: ImmutableNotebook; notebookContentRef: string; imageSrc: string; onError: (formError: string, formErrorDetail: string, area: string) => void; clearFormError: () => void; setNotebookName: (newValue: string) => void; setNotebookDescription: (newValue: string) => void; setNotebookTags: (newValue: string) => void; setImageSrc: (newValue: string) => void; onTakeSnapshot: (request: SnapshotRequest) => void; } enum ImageTypes { Url = "URL", CustomImage = "Custom Image", TakeScreenshot = "Take Screenshot", UseFirstDisplayOutput = "Use First Display Output", } export const PublishNotebookPaneComponent: FunctionComponent = ({ notebookName, notebookTags, notebookDescription, notebookAuthor, notebookCreatedDate, notebookObject, notebookContentRef, imageSrc, onError, clearFormError, setNotebookName, setNotebookDescription, setNotebookTags, setImageSrc, onTakeSnapshot, }: PublishNotebookPaneProps) => { const [type, setType] = useState(ImageTypes.CustomImage); const CARD_WIDTH = 256; const cardImageHeight = 144; const cardHeightToWidthRatio = cardImageHeight / CARD_WIDTH; const maxImageSizeInMib = 1.5; const descriptionPara1 = "When published, this notebook will appear in the Azure Cosmos DB notebooks public gallery. Make sure you have removed any sensitive data or output before publishing."; const descriptionPara2 = `Would you like to publish and share "${FileSystemUtil.stripExtension( notebookName, "ipynb" )}" to the gallery?`; const options: ImageTypes[] = [ImageTypes.CustomImage, ImageTypes.Url]; if (onTakeSnapshot) { options.push(ImageTypes.TakeScreenshot); if (notebookObject) { options.push(ImageTypes.UseFirstDisplayOutput); } } const thumbnailSelectorProps: IDropdownProps = { label: "Cover image", selectedKey: type, ariaLabel: "Cover image", options: options.map((value: string) => ({ text: value, key: value })), onChange: async (event, options) => { setImageSrc(""); clearFormError(); if (options.text === ImageTypes.TakeScreenshot) { onTakeSnapshot({ aspectRatio: cardHeightToWidthRatio, requestId: new Date().getTime().toString(), type: "notebook", notebookContentRef, }); } else if (options.text === ImageTypes.UseFirstDisplayOutput) { const cellIds = NotebookUtil.findCodeCellWithDisplay(notebookObject); if (cellIds.length > 0) { onTakeSnapshot({ aspectRatio: cardHeightToWidthRatio, requestId: new Date().getTime().toString(), type: "celloutput", cellId: cellIds[0], notebookContentRef, }); } else { firstOutputErrorHandler(new Error("Output does not exist for any of the cells.")); } } setType(options.text); }, }; const thumbnailUrlProps: ITextFieldProps = { label: "Cover image url", ariaLabel: "Cover image url", required: true, onChange: (event, newValue) => { setImageSrc(newValue); }, }; const firstOutputErrorHandler = (error: Error) => { const formError = "Failed to capture first output"; const formErrorDetail = `${error}`; const area = "PublishNotebookPaneComponent/UseFirstOutput"; onError(formError, formErrorDetail, area); }; const imageToBase64 = (file: File, updateImageSrc: (result: string) => void) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { updateImageSrc(reader.result.toString()); }; reader.onerror = (error) => { const formError = `Failed to convert ${file.name} to base64 format`; const formErrorDetail = `${error}`; const area = "PublishNotebookPaneComponent/selectImageFile"; onError(formError, formErrorDetail, area); }; }; const renderThumbnailSelectors = (type: string) => { switch (type) { case ImageTypes.Url: return ; case ImageTypes.CustomImage: return ( { const file = event.target.files[0]; if (file.size / 1024 ** 2 > maxImageSizeInMib) { event.target.value = ""; const formError = `Failed to upload ${file.name}`; const formErrorDetail = `Image is larger than ${maxImageSizeInMib} MiB. Please Choose a different image.`; const area = "PublishNotebookPaneComponent/selectImageFile"; onError(formError, formErrorDetail, area); setImageSrc(""); return; } else { clearFormError(); } imageToBase64(file, (result: string) => { setImageSrc(result); }); }} /> ); default: return <>; } }; return (
{descriptionPara1} {descriptionPara2} { const notebookName = newValue + ".ipynb"; setNotebookName(notebookName); }} /> { setNotebookDescription(newValue); }} /> { setNotebookTags(newValue); }} /> {renderThumbnailSelectors(type)} Preview undefined} onTagClick={undefined} onFavoriteClick={undefined} onUnfavoriteClick={undefined} onDownloadClick={undefined} onDeleteClick={undefined} />
); };