diff --git a/src/Explorer/Controls/NotebookGallery/Cards/GalleryCardComponent.tsx b/src/Explorer/Controls/NotebookGallery/Cards/GalleryCardComponent.tsx index 7fd7f6ff7..85f3087ae 100644 --- a/src/Explorer/Controls/NotebookGallery/Cards/GalleryCardComponent.tsx +++ b/src/Explorer/Controls/NotebookGallery/Cards/GalleryCardComponent.tsx @@ -13,6 +13,8 @@ import { LinkBase, Separator, TooltipHost, + Spinner, + SpinnerSize, } from "office-ui-fabric-react"; import * as React from "react"; import { IGalleryItem } from "../../../../Juno/JunoClient"; @@ -29,10 +31,14 @@ export interface GalleryCardComponentProps { onFavoriteClick: () => void; onUnfavoriteClick: () => void; onDownloadClick: () => void; - onDeleteClick: () => void; + onDeleteClick: (beforeDelete: () => void, afterDelete: () => void) => void; } -export class GalleryCardComponent extends React.Component { +interface GalleryCardComponentState { + isDeletingPublishedNotebook: boolean; +} + +export class GalleryCardComponent extends React.Component { public static readonly CARD_WIDTH = 256; private static readonly cardImageHeight = 144; public static readonly cardHeightToWidthRatio = @@ -40,6 +46,14 @@ export class GalleryCardComponent extends React.Component this.onClick(event, this.props.onClick)} > - - - + {this.state.isDeletingPublishedNotebook && ( + + + + )} + {!this.state.isDeletingPublishedNotebook && ( + <> + + + - - {`${cardTitle} - + + {`${cardTitle} + - - - {this.props.data.tags ? ( - this.props.data.tags.map((tag, index, array) => ( - - this.onClick(event, () => this.props.onTagClick(tag))}>{tag} - {index === array.length - 1 ? <> : ", "} - - )) - ) : ( -
- )} -
- - - {cardTitle} - - - - {this.renderTruncatedDescription()} - - - - {this.props.data.views !== undefined && this.generateIconText("RedEye", this.props.data.views.toString())} - {this.props.data.downloads !== undefined && - this.generateIconText("Download", this.props.data.downloads.toString())} - {this.props.data.favorites !== undefined && - this.generateIconText("Heart", this.props.data.favorites.toString())} - -
- - {cardButtonsVisible && ( - - - - - {this.props.isFavorite !== undefined && - this.generateIconButtonWithTooltip( - this.props.isFavorite ? "HeartFill" : "Heart", - this.props.isFavorite ? "Unfavorite" : "Favorite", - "left", - this.props.isFavorite ? this.props.onUnfavoriteClick : this.props.onFavoriteClick + + + {this.props.data.tags ? ( + this.props.data.tags.map((tag, index, array) => ( + + this.onClick(event, () => this.props.onTagClick(tag))}>{tag} + {index === array.length - 1 ? <> : ", "} + + )) + ) : ( +
)} +
- {this.props.showDownload && - this.generateIconButtonWithTooltip("Download", "Download", "left", this.props.onDownloadClick)} + + {cardTitle} + - {this.props.showDelete && - this.generateIconButtonWithTooltip("Delete", "Remove", "right", this.props.onDeleteClick)} -
-
+ + {this.renderTruncatedDescription()} + + + + {this.props.data.views !== undefined && + this.generateIconText("RedEye", this.props.data.views.toString())} + {this.props.data.downloads !== undefined && + this.generateIconText("Download", this.props.data.downloads.toString())} + {this.props.data.favorites !== undefined && + this.generateIconText("Heart", this.props.data.favorites.toString())} + + + + {cardButtonsVisible && ( + + + + + {this.props.isFavorite !== undefined && + this.generateIconButtonWithTooltip( + this.props.isFavorite ? "HeartFill" : "Heart", + this.props.isFavorite ? "Unfavorite" : "Favorite", + "left", + this.props.isFavorite ? this.props.onUnfavoriteClick : this.props.onFavoriteClick + )} + + {this.props.showDownload && + this.generateIconButtonWithTooltip("Download", "Download", "left", this.props.onDownloadClick)} + + {this.props.showDelete && + this.generateIconButtonWithTooltip("Delete", "Remove", "right", () => + this.props.onDeleteClick( + () => this.setState({ isDeletingPublishedNotebook: true }), + () => this.setState({ isDeletingPublishedNotebook: false }) + ) + )} + + + )} + )} ); diff --git a/src/Explorer/Controls/NotebookGallery/GalleryViewerComponent.tsx b/src/Explorer/Controls/NotebookGallery/GalleryViewerComponent.tsx index ce557baa7..1dc313340 100644 --- a/src/Explorer/Controls/NotebookGallery/GalleryViewerComponent.tsx +++ b/src/Explorer/Controls/NotebookGallery/GalleryViewerComponent.tsx @@ -666,7 +666,8 @@ export class GalleryViewerComponent extends React.Component this.favoriteItem(data), onUnfavoriteClick: () => this.unfavoriteItem(data), onDownloadClick: () => this.downloadItem(data), - onDeleteClick: () => this.deleteItem(data), + onDeleteClick: (beforeDelete: () => void, afterDelete: () => void) => + this.deleteItem(data, beforeDelete, afterDelete), }; return ( @@ -710,11 +711,18 @@ export class GalleryViewerComponent extends React.Component => { - GalleryUtils.deleteItem(this.props.container, this.props.junoClient, data, (item) => { - this.publishedNotebooks = this.publishedNotebooks?.filter((notebook) => item.id !== notebook.id); - this.refreshSelectedTab(item); - }); + private deleteItem = async (data: IGalleryItem, beforeDelete: () => void, afterDelete: () => void): Promise => { + GalleryUtils.deleteItem( + this.props.container, + this.props.junoClient, + data, + (item) => { + this.publishedNotebooks = this.publishedNotebooks?.filter((notebook) => item.id !== notebook.id); + this.refreshSelectedTab(item); + }, + beforeDelete, + afterDelete + ); }; private onPivotChange = (item: PivotItem): void => { diff --git a/src/Utils/GalleryUtils.ts b/src/Utils/GalleryUtils.ts index 4a56c8900..d0cd0999c 100644 --- a/src/Utils/GalleryUtils.ts +++ b/src/Utils/GalleryUtils.ts @@ -373,7 +373,9 @@ export function deleteItem( container: Explorer, junoClient: JunoClient, data: IGalleryItem, - onComplete: (item: IGalleryItem) => void + onComplete: (item: IGalleryItem) => void, + beforeDelete?: () => void, + afterDelete?: () => void ): void { if (container) { trace(Action.NotebooksGalleryClickDelete, ActionModifiers.Mark, { notebookId: data.id }); @@ -383,6 +385,9 @@ export function deleteItem( `Would you like to remove ${data.name} from the gallery?`, "Remove", async () => { + if (beforeDelete) { + beforeDelete(); + } const name = data.name; const notificationId = NotificationConsoleUtils.logConsoleMessage( ConsoleDataType.InProgress, @@ -409,6 +414,10 @@ export function deleteItem( ); handleError(error, "GalleryUtils/deleteItem", `Failed to remove ${name} from gallery`); + } finally { + if (afterDelete) { + afterDelete(); + } } NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);