mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-06-05 15:12:04 +01:00
Added spinner for notebook delete (#458)
* initial UI for delete published nb spinner * added notebook delete spinner * addressed PR comments
This commit is contained in:
parent
4127d0f522
commit
b8e9903287
@ -13,6 +13,8 @@ import {
|
|||||||
LinkBase,
|
LinkBase,
|
||||||
Separator,
|
Separator,
|
||||||
TooltipHost,
|
TooltipHost,
|
||||||
|
Spinner,
|
||||||
|
SpinnerSize,
|
||||||
} from "office-ui-fabric-react";
|
} from "office-ui-fabric-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { IGalleryItem } from "../../../../Juno/JunoClient";
|
import { IGalleryItem } from "../../../../Juno/JunoClient";
|
||||||
@ -29,10 +31,14 @@ export interface GalleryCardComponentProps {
|
|||||||
onFavoriteClick: () => void;
|
onFavoriteClick: () => void;
|
||||||
onUnfavoriteClick: () => void;
|
onUnfavoriteClick: () => void;
|
||||||
onDownloadClick: () => void;
|
onDownloadClick: () => void;
|
||||||
onDeleteClick: () => void;
|
onDeleteClick: (beforeDelete: () => void, afterDelete: () => void) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GalleryCardComponent extends React.Component<GalleryCardComponentProps> {
|
interface GalleryCardComponentState {
|
||||||
|
isDeletingPublishedNotebook: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GalleryCardComponent extends React.Component<GalleryCardComponentProps, GalleryCardComponentState> {
|
||||||
public static readonly CARD_WIDTH = 256;
|
public static readonly CARD_WIDTH = 256;
|
||||||
private static readonly cardImageHeight = 144;
|
private static readonly cardImageHeight = 144;
|
||||||
public static readonly cardHeightToWidthRatio =
|
public static readonly cardHeightToWidthRatio =
|
||||||
@ -40,6 +46,14 @@ export class GalleryCardComponent extends React.Component<GalleryCardComponentPr
|
|||||||
private static readonly cardDescriptionMaxChars = 80;
|
private static readonly cardDescriptionMaxChars = 80;
|
||||||
private static readonly cardItemGapBig = 10;
|
private static readonly cardItemGapBig = 10;
|
||||||
private static readonly cardItemGapSmall = 8;
|
private static readonly cardItemGapSmall = 8;
|
||||||
|
private static readonly cardDeleteSpinnerHeight = 360;
|
||||||
|
|
||||||
|
constructor(props: GalleryCardComponentProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isDeletingPublishedNotebook: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
const cardButtonsVisible = this.props.isFavorite !== undefined || this.props.showDownload || this.props.showDelete;
|
const cardButtonsVisible = this.props.isFavorite !== undefined || this.props.showDownload || this.props.showDelete;
|
||||||
@ -59,6 +73,17 @@ export class GalleryCardComponent extends React.Component<GalleryCardComponentPr
|
|||||||
tokens={{ width: GalleryCardComponent.CARD_WIDTH, childrenGap: 0 }}
|
tokens={{ width: GalleryCardComponent.CARD_WIDTH, childrenGap: 0 }}
|
||||||
onClick={(event) => this.onClick(event, this.props.onClick)}
|
onClick={(event) => this.onClick(event, this.props.onClick)}
|
||||||
>
|
>
|
||||||
|
{this.state.isDeletingPublishedNotebook && (
|
||||||
|
<Card.Item tokens={{ padding: GalleryCardComponent.cardItemGapBig }}>
|
||||||
|
<Spinner
|
||||||
|
size={SpinnerSize.large}
|
||||||
|
label={`Deleting '${cardTitle}'`}
|
||||||
|
styles={{ root: { height: GalleryCardComponent.cardDeleteSpinnerHeight } }}
|
||||||
|
/>
|
||||||
|
</Card.Item>
|
||||||
|
)}
|
||||||
|
{!this.state.isDeletingPublishedNotebook && (
|
||||||
|
<>
|
||||||
<Card.Item tokens={{ padding: GalleryCardComponent.cardItemGapBig }}>
|
<Card.Item tokens={{ padding: GalleryCardComponent.cardItemGapBig }}>
|
||||||
<Persona
|
<Persona
|
||||||
imageUrl={this.props.data.isSample && CosmosDBLogo}
|
imageUrl={this.props.data.isSample && CosmosDBLogo}
|
||||||
@ -109,7 +134,8 @@ export class GalleryCardComponent extends React.Component<GalleryCardComponentPr
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{this.props.data.views !== undefined && this.generateIconText("RedEye", this.props.data.views.toString())}
|
{this.props.data.views !== undefined &&
|
||||||
|
this.generateIconText("RedEye", this.props.data.views.toString())}
|
||||||
{this.props.data.downloads !== undefined &&
|
{this.props.data.downloads !== undefined &&
|
||||||
this.generateIconText("Download", this.props.data.downloads.toString())}
|
this.generateIconText("Download", this.props.data.downloads.toString())}
|
||||||
{this.props.data.favorites !== undefined &&
|
{this.props.data.favorites !== undefined &&
|
||||||
@ -141,10 +167,17 @@ export class GalleryCardComponent extends React.Component<GalleryCardComponentPr
|
|||||||
this.generateIconButtonWithTooltip("Download", "Download", "left", this.props.onDownloadClick)}
|
this.generateIconButtonWithTooltip("Download", "Download", "left", this.props.onDownloadClick)}
|
||||||
|
|
||||||
{this.props.showDelete &&
|
{this.props.showDelete &&
|
||||||
this.generateIconButtonWithTooltip("Delete", "Remove", "right", this.props.onDeleteClick)}
|
this.generateIconButtonWithTooltip("Delete", "Remove", "right", () =>
|
||||||
|
this.props.onDeleteClick(
|
||||||
|
() => this.setState({ isDeletingPublishedNotebook: true }),
|
||||||
|
() => this.setState({ isDeletingPublishedNotebook: false })
|
||||||
|
)
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</Card.Section>
|
</Card.Section>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -666,7 +666,8 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
|||||||
onFavoriteClick: () => this.favoriteItem(data),
|
onFavoriteClick: () => this.favoriteItem(data),
|
||||||
onUnfavoriteClick: () => this.unfavoriteItem(data),
|
onUnfavoriteClick: () => this.unfavoriteItem(data),
|
||||||
onDownloadClick: () => this.downloadItem(data),
|
onDownloadClick: () => this.downloadItem(data),
|
||||||
onDeleteClick: () => this.deleteItem(data),
|
onDeleteClick: (beforeDelete: () => void, afterDelete: () => void) =>
|
||||||
|
this.deleteItem(data, beforeDelete, afterDelete),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -710,11 +711,18 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
private deleteItem = async (data: IGalleryItem): Promise<void> => {
|
private deleteItem = async (data: IGalleryItem, beforeDelete: () => void, afterDelete: () => void): Promise<void> => {
|
||||||
GalleryUtils.deleteItem(this.props.container, this.props.junoClient, data, (item) => {
|
GalleryUtils.deleteItem(
|
||||||
|
this.props.container,
|
||||||
|
this.props.junoClient,
|
||||||
|
data,
|
||||||
|
(item) => {
|
||||||
this.publishedNotebooks = this.publishedNotebooks?.filter((notebook) => item.id !== notebook.id);
|
this.publishedNotebooks = this.publishedNotebooks?.filter((notebook) => item.id !== notebook.id);
|
||||||
this.refreshSelectedTab(item);
|
this.refreshSelectedTab(item);
|
||||||
});
|
},
|
||||||
|
beforeDelete,
|
||||||
|
afterDelete
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onPivotChange = (item: PivotItem): void => {
|
private onPivotChange = (item: PivotItem): void => {
|
||||||
|
@ -373,7 +373,9 @@ export function deleteItem(
|
|||||||
container: Explorer,
|
container: Explorer,
|
||||||
junoClient: JunoClient,
|
junoClient: JunoClient,
|
||||||
data: IGalleryItem,
|
data: IGalleryItem,
|
||||||
onComplete: (item: IGalleryItem) => void
|
onComplete: (item: IGalleryItem) => void,
|
||||||
|
beforeDelete?: () => void,
|
||||||
|
afterDelete?: () => void
|
||||||
): void {
|
): void {
|
||||||
if (container) {
|
if (container) {
|
||||||
trace(Action.NotebooksGalleryClickDelete, ActionModifiers.Mark, { notebookId: data.id });
|
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?`,
|
`Would you like to remove ${data.name} from the gallery?`,
|
||||||
"Remove",
|
"Remove",
|
||||||
async () => {
|
async () => {
|
||||||
|
if (beforeDelete) {
|
||||||
|
beforeDelete();
|
||||||
|
}
|
||||||
const name = data.name;
|
const name = data.name;
|
||||||
const notificationId = NotificationConsoleUtils.logConsoleMessage(
|
const notificationId = NotificationConsoleUtils.logConsoleMessage(
|
||||||
ConsoleDataType.InProgress,
|
ConsoleDataType.InProgress,
|
||||||
@ -409,6 +414,10 @@ export function deleteItem(
|
|||||||
);
|
);
|
||||||
|
|
||||||
handleError(error, "GalleryUtils/deleteItem", `Failed to remove ${name} from gallery`);
|
handleError(error, "GalleryUtils/deleteItem", `Failed to remove ${name} from gallery`);
|
||||||
|
} finally {
|
||||||
|
if (afterDelete) {
|
||||||
|
afterDelete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
|
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user