2020-06-30 11:47:21 -07:00
|
|
|
import {
|
|
|
|
Dropdown,
|
|
|
|
FocusZone,
|
|
|
|
IDropdownOption,
|
|
|
|
IPageSpecification,
|
|
|
|
IPivotItemProps,
|
|
|
|
IPivotProps,
|
|
|
|
IRectangle,
|
|
|
|
Label,
|
|
|
|
List,
|
|
|
|
Pivot,
|
|
|
|
PivotItem,
|
|
|
|
SearchBox,
|
|
|
|
Stack
|
|
|
|
} from "office-ui-fabric-react";
|
2020-06-05 04:04:15 +02:00
|
|
|
import * as React from "react";
|
2020-06-30 11:47:21 -07:00
|
|
|
import * as Logger from "../../../Common/Logger";
|
2020-06-05 04:04:15 +02:00
|
|
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
2020-06-30 11:47:21 -07:00
|
|
|
import { IGalleryItem, JunoClient } from "../../../Juno/JunoClient";
|
|
|
|
import * as GalleryUtils from "../../../Utils/GalleryUtils";
|
2020-06-05 04:04:15 +02:00
|
|
|
import { NotificationConsoleUtils } from "../../../Utils/NotificationConsoleUtils";
|
|
|
|
import { ConsoleDataType } from "../../Menus/NotificationConsole/NotificationConsoleComponent";
|
2020-06-30 11:47:21 -07:00
|
|
|
import { DialogComponent, DialogProps } from "../DialogReactComponent/DialogComponent";
|
|
|
|
import { GalleryCardComponent, GalleryCardComponentProps } from "./Cards/GalleryCardComponent";
|
2020-06-05 04:04:15 +02:00
|
|
|
import "./GalleryViewerComponent.less";
|
2020-06-30 11:47:21 -07:00
|
|
|
import { HttpStatusCodes } from "../../../Common/Constants";
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
export interface GalleryViewerComponentProps {
|
|
|
|
container?: ViewModels.Explorer;
|
|
|
|
junoClient: JunoClient;
|
|
|
|
selectedTab: GalleryTab;
|
|
|
|
sortBy: SortBy;
|
|
|
|
searchText: string;
|
2020-07-15 13:58:43 -07:00
|
|
|
openNotebook: (data: IGalleryItem, isFavorite: boolean) => void;
|
2020-06-30 11:47:21 -07:00
|
|
|
onSelectedTabChange: (newTab: GalleryTab) => void;
|
|
|
|
onSortByChange: (sortBy: SortBy) => void;
|
|
|
|
onSearchTextChange: (searchText: string) => void;
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
export enum GalleryTab {
|
|
|
|
OfficialSamples,
|
|
|
|
PublicGallery,
|
|
|
|
Favorites,
|
|
|
|
Published
|
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
export enum SortBy {
|
|
|
|
MostViewed,
|
|
|
|
MostDownloaded,
|
|
|
|
MostFavorited,
|
|
|
|
MostRecent
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
interface GalleryViewerComponentState {
|
|
|
|
sampleNotebooks: IGalleryItem[];
|
|
|
|
publicNotebooks: IGalleryItem[];
|
|
|
|
favoriteNotebooks: IGalleryItem[];
|
|
|
|
publishedNotebooks: IGalleryItem[];
|
|
|
|
selectedTab: GalleryTab;
|
|
|
|
sortBy: SortBy;
|
|
|
|
searchText: string;
|
|
|
|
dialogProps: DialogProps;
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
interface GalleryTabInfo {
|
|
|
|
tab: GalleryTab;
|
|
|
|
content: JSX.Element;
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-07-15 13:58:43 -07:00
|
|
|
export class GalleryViewerComponent extends React.Component<GalleryViewerComponentProps, GalleryViewerComponentState> {
|
2020-06-30 11:47:21 -07:00
|
|
|
public static readonly OfficialSamplesTitle = "Official samples";
|
|
|
|
public static readonly PublicGalleryTitle = "Public gallery";
|
|
|
|
public static readonly FavoritesTitle = "Liked";
|
|
|
|
public static readonly PublishedTitle = "Your published work";
|
|
|
|
|
2020-07-15 13:58:43 -07:00
|
|
|
private static readonly rowsPerPage = 5;
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private static readonly mostViewedText = "Most viewed";
|
|
|
|
private static readonly mostDownloadedText = "Most downloaded";
|
2020-07-06 12:10:26 -07:00
|
|
|
private static readonly mostFavoritedText = "Most liked";
|
2020-06-30 11:47:21 -07:00
|
|
|
private static readonly mostRecentText = "Most recent";
|
|
|
|
|
2020-07-06 12:10:26 -07:00
|
|
|
private readonly sortingOptions: IDropdownOption[];
|
2020-06-30 11:47:21 -07:00
|
|
|
|
|
|
|
private sampleNotebooks: IGalleryItem[];
|
|
|
|
private publicNotebooks: IGalleryItem[];
|
|
|
|
private favoriteNotebooks: IGalleryItem[];
|
|
|
|
private publishedNotebooks: IGalleryItem[];
|
|
|
|
private columnCount: number;
|
|
|
|
private rowCount: number;
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
constructor(props: GalleryViewerComponentProps) {
|
2020-06-05 04:04:15 +02:00
|
|
|
super(props);
|
2020-06-30 11:47:21 -07:00
|
|
|
|
2020-06-05 04:04:15 +02:00
|
|
|
this.state = {
|
2020-06-30 11:47:21 -07:00
|
|
|
sampleNotebooks: undefined,
|
|
|
|
publicNotebooks: undefined,
|
|
|
|
favoriteNotebooks: undefined,
|
|
|
|
publishedNotebooks: undefined,
|
|
|
|
selectedTab: props.selectedTab,
|
|
|
|
sortBy: props.sortBy,
|
|
|
|
searchText: props.searchText,
|
|
|
|
dialogProps: undefined
|
2020-06-05 04:04:15 +02:00
|
|
|
};
|
|
|
|
|
2020-07-06 12:10:26 -07:00
|
|
|
this.sortingOptions = [
|
|
|
|
{
|
|
|
|
key: SortBy.MostViewed,
|
|
|
|
text: GalleryViewerComponent.mostViewedText
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: SortBy.MostDownloaded,
|
|
|
|
text: GalleryViewerComponent.mostDownloadedText
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: SortBy.MostRecent,
|
|
|
|
text: GalleryViewerComponent.mostRecentText
|
|
|
|
}
|
|
|
|
];
|
|
|
|
if (this.props.container?.isGalleryPublishEnabled()) {
|
|
|
|
this.sortingOptions.push({
|
|
|
|
key: SortBy.MostFavorited,
|
|
|
|
text: GalleryViewerComponent.mostFavoritedText
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
this.loadTabContent(this.state.selectedTab, this.state.searchText, this.state.sortBy, false);
|
2020-07-06 12:10:26 -07:00
|
|
|
if (this.props.container?.isGalleryPublishEnabled()) {
|
2020-06-30 11:47:21 -07:00
|
|
|
this.loadFavoriteNotebooks(this.state.searchText, this.state.sortBy, false); // Need this to show correct favorite button state
|
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
public render(): JSX.Element {
|
|
|
|
const tabs: GalleryTabInfo[] = [this.createTab(GalleryTab.OfficialSamples, this.state.sampleNotebooks)];
|
|
|
|
|
2020-07-06 12:10:26 -07:00
|
|
|
if (this.props.container?.isGalleryPublishEnabled()) {
|
|
|
|
tabs.push(this.createTab(GalleryTab.PublicGallery, this.state.publicNotebooks));
|
2020-06-30 11:47:21 -07:00
|
|
|
tabs.push(this.createTab(GalleryTab.Favorites, this.state.favoriteNotebooks));
|
2020-07-06 12:10:26 -07:00
|
|
|
tabs.push(this.createTab(GalleryTab.Published, this.state.publishedNotebooks));
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
const pivotProps: IPivotProps = {
|
|
|
|
onLinkClick: this.onPivotChange,
|
|
|
|
selectedKey: GalleryTab[this.state.selectedTab]
|
|
|
|
};
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
const pivotItems = tabs.map(tab => {
|
|
|
|
const pivotItemProps: IPivotItemProps = {
|
|
|
|
itemKey: GalleryTab[tab.tab],
|
|
|
|
style: { marginTop: 20 },
|
|
|
|
headerText: GalleryUtils.getTabTitle(tab.tab)
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<PivotItem key={pivotItemProps.itemKey} {...pivotItemProps}>
|
|
|
|
{tab.content}
|
|
|
|
</PivotItem>
|
|
|
|
);
|
2020-06-05 04:04:15 +02:00
|
|
|
});
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
return (
|
|
|
|
<div className="galleryContainer">
|
|
|
|
<Pivot {...pivotProps}>{pivotItems}</Pivot>
|
|
|
|
|
|
|
|
{this.state.dialogProps && <DialogComponent {...this.state.dialogProps} />}
|
|
|
|
</div>
|
2020-06-05 04:04:15 +02:00
|
|
|
);
|
2020-06-30 11:47:21 -07:00
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private createTab(tab: GalleryTab, data: IGalleryItem[]): GalleryTabInfo {
|
|
|
|
return {
|
|
|
|
tab,
|
|
|
|
content: this.createTabContent(data)
|
|
|
|
};
|
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private createTabContent(data: IGalleryItem[]): JSX.Element {
|
2020-06-05 04:04:15 +02:00
|
|
|
return (
|
2020-07-15 13:58:43 -07:00
|
|
|
<Stack tokens={{ childrenGap: 10 }}>
|
|
|
|
<Stack horizontal tokens={{ childrenGap: 20, padding: 10 }}>
|
2020-06-30 11:47:21 -07:00
|
|
|
<Stack.Item grow>
|
|
|
|
<SearchBox value={this.state.searchText} placeholder="Search" onChange={this.onSearchBoxChange} />
|
|
|
|
</Stack.Item>
|
|
|
|
<Stack.Item>
|
|
|
|
<Label>Sort by</Label>
|
|
|
|
</Stack.Item>
|
|
|
|
<Stack.Item styles={{ root: { minWidth: 200 } }}>
|
2020-07-06 12:10:26 -07:00
|
|
|
<Dropdown options={this.sortingOptions} selectedKey={this.state.sortBy} onChange={this.onDropdownChange} />
|
2020-06-30 11:47:21 -07:00
|
|
|
</Stack.Item>
|
|
|
|
</Stack>
|
|
|
|
|
|
|
|
{data && this.createCardsTabContent(data)}
|
|
|
|
</Stack>
|
2020-06-05 04:04:15 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private createCardsTabContent(data: IGalleryItem[]): JSX.Element {
|
|
|
|
return (
|
|
|
|
<FocusZone>
|
|
|
|
<List
|
|
|
|
items={data}
|
|
|
|
getPageSpecification={this.getPageSpecification}
|
|
|
|
renderedWindowsAhead={3}
|
|
|
|
onRenderCell={this.onRenderCell}
|
|
|
|
/>
|
|
|
|
</FocusZone>
|
|
|
|
);
|
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private loadTabContent(tab: GalleryTab, searchText: string, sortBy: SortBy, offline: boolean): void {
|
|
|
|
switch (tab) {
|
|
|
|
case GalleryTab.OfficialSamples:
|
|
|
|
this.loadSampleNotebooks(searchText, sortBy, offline);
|
|
|
|
break;
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
case GalleryTab.PublicGallery:
|
|
|
|
this.loadPublicNotebooks(searchText, sortBy, offline);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GalleryTab.Favorites:
|
|
|
|
this.loadFavoriteNotebooks(searchText, sortBy, offline);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GalleryTab.Published:
|
|
|
|
this.loadPublishedNotebooks(searchText, sortBy, offline);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new Error(`Unknown tab ${tab}`);
|
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private async loadSampleNotebooks(searchText: string, sortBy: SortBy, offline: boolean): Promise<void> {
|
|
|
|
if (!offline) {
|
|
|
|
try {
|
|
|
|
const response = await this.props.junoClient.getSampleNotebooks();
|
|
|
|
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
|
|
|
throw new Error(`Received HTTP ${response.status} when loading sample notebooks`);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.sampleNotebooks = response.data;
|
|
|
|
} catch (error) {
|
|
|
|
const message = `Failed to load sample notebooks: ${error}`;
|
|
|
|
Logger.logError(message, "GalleryViewerComponent/loadSampleNotebooks");
|
|
|
|
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, message);
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
2020-06-30 11:47:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
sampleNotebooks: this.sampleNotebooks && [...this.sort(sortBy, this.search(searchText, this.sampleNotebooks))]
|
|
|
|
});
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private async loadPublicNotebooks(searchText: string, sortBy: SortBy, offline: boolean): Promise<void> {
|
|
|
|
if (!offline) {
|
|
|
|
try {
|
|
|
|
const response = await this.props.junoClient.getPublicNotebooks();
|
|
|
|
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
|
|
|
throw new Error(`Received HTTP ${response.status} when loading public notebooks`);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.publicNotebooks = response.data;
|
|
|
|
} catch (error) {
|
|
|
|
const message = `Failed to load public notebooks: ${error}`;
|
|
|
|
Logger.logError(message, "GalleryViewerComponent/loadPublicNotebooks");
|
|
|
|
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
publicNotebooks: this.publicNotebooks && [...this.sort(sortBy, this.search(searchText, this.publicNotebooks))]
|
|
|
|
});
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private async loadFavoriteNotebooks(searchText: string, sortBy: SortBy, offline: boolean): Promise<void> {
|
|
|
|
if (!offline) {
|
|
|
|
try {
|
|
|
|
const response = await this.props.junoClient.getFavoriteNotebooks();
|
|
|
|
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
|
|
|
throw new Error(`Received HTTP ${response.status} when loading favorite notebooks`);
|
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
this.favoriteNotebooks = response.data;
|
|
|
|
} catch (error) {
|
|
|
|
const message = `Failed to load favorite notebooks: ${error}`;
|
|
|
|
Logger.logError(message, "GalleryViewerComponent/loadFavoriteNotebooks");
|
|
|
|
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
favoriteNotebooks: this.favoriteNotebooks && [
|
|
|
|
...this.sort(sortBy, this.search(searchText, this.favoriteNotebooks))
|
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
// Refresh favorite button state
|
|
|
|
if (this.state.selectedTab !== GalleryTab.Favorites) {
|
|
|
|
this.refreshSelectedTab();
|
|
|
|
}
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private async loadPublishedNotebooks(searchText: string, sortBy: SortBy, offline: boolean): Promise<void> {
|
|
|
|
if (!offline) {
|
|
|
|
try {
|
|
|
|
const response = await this.props.junoClient.getPublishedNotebooks();
|
|
|
|
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
|
|
|
throw new Error(`Received HTTP ${response.status} when loading published notebooks`);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.publishedNotebooks = response.data;
|
|
|
|
} catch (error) {
|
|
|
|
const message = `Failed to load published notebooks: ${error}`;
|
|
|
|
Logger.logError(message, "GalleryViewerComponent/loadPublishedNotebooks");
|
|
|
|
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
publishedNotebooks: this.publishedNotebooks && [
|
|
|
|
...this.sort(sortBy, this.search(searchText, this.publishedNotebooks))
|
|
|
|
]
|
|
|
|
});
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private search(searchText: string, data: IGalleryItem[]): IGalleryItem[] {
|
|
|
|
if (searchText) {
|
|
|
|
return data?.filter(item => this.isGalleryItemPresent(searchText, item));
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 11:47:21 -07:00
|
|
|
private isGalleryItemPresent(searchText: string, item: IGalleryItem): boolean {
|
|
|
|
const toSearch = searchText.trim().toUpperCase();
|
|
|
|
const searchData: string[] = [
|
|
|
|
item.author.toUpperCase(),
|
|
|
|
item.description.toUpperCase(),
|
|
|
|
item.name.toUpperCase(),
|
|
|
|
...item.tags?.map(tag => tag.toUpperCase())
|
|
|
|
];
|
|
|
|
|
|
|
|
for (const data of searchData) {
|
|
|
|
if (data?.indexOf(toSearch) !== -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private sort(sortBy: SortBy, data: IGalleryItem[]): IGalleryItem[] {
|
|
|
|
return data?.sort((a, b) => {
|
|
|
|
switch (sortBy) {
|
|
|
|
case SortBy.MostViewed:
|
|
|
|
return b.views - a.views;
|
|
|
|
case SortBy.MostDownloaded:
|
|
|
|
return b.downloads - a.downloads;
|
|
|
|
case SortBy.MostFavorited:
|
|
|
|
return b.favorites - a.favorites;
|
|
|
|
case SortBy.MostRecent:
|
|
|
|
return Date.parse(b.created) - Date.parse(a.created);
|
|
|
|
default:
|
|
|
|
throw new Error(`Unknown sorting condition ${sortBy}`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private refreshSelectedTab(item?: IGalleryItem): void {
|
|
|
|
if (item) {
|
|
|
|
this.updateGalleryItem(item);
|
|
|
|
}
|
|
|
|
this.loadTabContent(this.state.selectedTab, this.state.searchText, this.state.sortBy, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
private updateGalleryItem(updatedItem: IGalleryItem): void {
|
|
|
|
this.replaceGalleryItem(updatedItem, this.sampleNotebooks);
|
|
|
|
this.replaceGalleryItem(updatedItem, this.publicNotebooks);
|
|
|
|
this.replaceGalleryItem(updatedItem, this.favoriteNotebooks);
|
|
|
|
this.replaceGalleryItem(updatedItem, this.publishedNotebooks);
|
|
|
|
}
|
|
|
|
|
|
|
|
private replaceGalleryItem(item: IGalleryItem, items?: IGalleryItem[]): void {
|
|
|
|
const index = items?.findIndex(value => value.id === item.id);
|
|
|
|
if (index !== -1) {
|
|
|
|
items?.splice(index, 1, item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private getPageSpecification = (itemIndex?: number, visibleRect?: IRectangle): IPageSpecification => {
|
2020-07-15 09:27:27 -07:00
|
|
|
if (itemIndex === 0) {
|
|
|
|
this.columnCount = Math.floor(visibleRect.width / GalleryCardComponent.CARD_WIDTH) || this.columnCount;
|
2020-07-15 13:58:43 -07:00
|
|
|
this.rowCount = GalleryViewerComponent.rowsPerPage;
|
2020-07-15 09:27:27 -07:00
|
|
|
}
|
2020-06-30 11:47:21 -07:00
|
|
|
|
|
|
|
return {
|
|
|
|
height: visibleRect.height,
|
|
|
|
itemCount: this.columnCount * this.rowCount
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
private onRenderCell = (data?: IGalleryItem): JSX.Element => {
|
2020-07-06 12:10:26 -07:00
|
|
|
let isFavorite: boolean;
|
|
|
|
if (this.props.container?.isGalleryPublishEnabled()) {
|
|
|
|
isFavorite = this.favoriteNotebooks?.find(item => item.id === data.id) !== undefined;
|
|
|
|
}
|
2020-06-30 11:47:21 -07:00
|
|
|
const props: GalleryCardComponentProps = {
|
|
|
|
data,
|
|
|
|
isFavorite,
|
2020-07-15 13:58:43 -07:00
|
|
|
showDownload: !!this.props.container,
|
2020-06-30 11:47:21 -07:00
|
|
|
showDelete: this.state.selectedTab === GalleryTab.Published,
|
2020-07-15 13:58:43 -07:00
|
|
|
onClick: () => this.props.openNotebook(data, isFavorite),
|
2020-06-30 11:47:21 -07:00
|
|
|
onTagClick: this.loadTaggedItems,
|
|
|
|
onFavoriteClick: () => this.favoriteItem(data),
|
|
|
|
onUnfavoriteClick: () => this.unfavoriteItem(data),
|
|
|
|
onDownloadClick: () => this.downloadItem(data),
|
|
|
|
onDeleteClick: () => this.deleteItem(data)
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div style={{ float: "left", padding: 10 }}>
|
|
|
|
<GalleryCardComponent {...props} />
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
private loadTaggedItems = (tag: string): void => {
|
|
|
|
const searchText = tag;
|
|
|
|
this.setState({
|
|
|
|
searchText
|
|
|
|
});
|
|
|
|
|
|
|
|
this.loadTabContent(this.state.selectedTab, searchText, this.state.sortBy, true);
|
|
|
|
this.props.onSearchTextChange && this.props.onSearchTextChange(searchText);
|
|
|
|
};
|
|
|
|
|
|
|
|
private favoriteItem = async (data: IGalleryItem): Promise<void> => {
|
|
|
|
GalleryUtils.favoriteItem(this.props.container, this.props.junoClient, data, (item: IGalleryItem) => {
|
|
|
|
if (this.favoriteNotebooks) {
|
|
|
|
this.favoriteNotebooks.push(item);
|
|
|
|
} else {
|
|
|
|
this.favoriteNotebooks = [item];
|
|
|
|
}
|
|
|
|
this.refreshSelectedTab(item);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
private unfavoriteItem = async (data: IGalleryItem): Promise<void> => {
|
|
|
|
GalleryUtils.unfavoriteItem(this.props.container, this.props.junoClient, data, (item: IGalleryItem) => {
|
|
|
|
this.favoriteNotebooks = this.favoriteNotebooks?.filter(value => value.id !== item.id);
|
|
|
|
this.refreshSelectedTab(item);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
private downloadItem = async (data: IGalleryItem): Promise<void> => {
|
2020-07-15 13:58:43 -07:00
|
|
|
GalleryUtils.downloadItem(this.props.container, this.props.junoClient, data, item => this.refreshSelectedTab(item));
|
2020-06-30 11:47:21 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
private deleteItem = async (data: IGalleryItem): Promise<void> => {
|
|
|
|
GalleryUtils.deleteItem(this.props.container, this.props.junoClient, data, item => {
|
|
|
|
this.publishedNotebooks = this.publishedNotebooks.filter(notebook => item.id !== notebook.id);
|
|
|
|
this.refreshSelectedTab(item);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
private onPivotChange = (item: PivotItem): void => {
|
|
|
|
const selectedTab = GalleryTab[item.props.itemKey as keyof typeof GalleryTab];
|
|
|
|
const searchText: string = undefined;
|
|
|
|
this.setState({
|
|
|
|
selectedTab,
|
|
|
|
searchText
|
|
|
|
});
|
|
|
|
|
|
|
|
this.loadTabContent(selectedTab, searchText, this.state.sortBy, false);
|
|
|
|
this.props.onSelectedTabChange && this.props.onSelectedTabChange(selectedTab);
|
|
|
|
};
|
|
|
|
|
|
|
|
private onSearchBoxChange = (event?: React.ChangeEvent<HTMLInputElement>, newValue?: string): void => {
|
|
|
|
const searchText = newValue;
|
|
|
|
this.setState({
|
|
|
|
searchText
|
|
|
|
});
|
|
|
|
|
|
|
|
this.loadTabContent(this.state.selectedTab, searchText, this.state.sortBy, true);
|
|
|
|
this.props.onSearchTextChange && this.props.onSearchTextChange(searchText);
|
|
|
|
};
|
|
|
|
|
|
|
|
private onDropdownChange = (event: React.FormEvent<HTMLDivElement>, option?: IDropdownOption): void => {
|
|
|
|
const sortBy = option.key as SortBy;
|
|
|
|
this.setState({
|
|
|
|
sortBy
|
|
|
|
});
|
|
|
|
|
|
|
|
this.loadTabContent(this.state.selectedTab, this.state.searchText, sortBy, true);
|
|
|
|
this.props.onSortByChange && this.props.onSortByChange(sortBy);
|
|
|
|
};
|
2020-06-05 04:04:15 +02:00
|
|
|
}
|