mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-16 17:25:58 +00:00
Public gallery improvements (#409)
- [x] Don't show extension in name field for publish - [x] Open "Your published work" tab after publishing - [x] Continue showing dialog for Report Abuse status - [x] For showing COC in Public Gallery tab show backdrop of thumbnails - [x] Liked -> My Favorites & Your published work -> My published work
This commit is contained in:
parent
59113d7bbf
commit
9278654479
@ -3,7 +3,13 @@ import { Dialog, DialogType, DialogFooter, IDialogProps } from "office-ui-fabric
|
|||||||
import { IButtonProps, PrimaryButton, DefaultButton } from "office-ui-fabric-react/lib/Button";
|
import { IButtonProps, PrimaryButton, DefaultButton } from "office-ui-fabric-react/lib/Button";
|
||||||
import { ITextFieldProps, TextField } from "office-ui-fabric-react/lib/TextField";
|
import { ITextFieldProps, TextField } from "office-ui-fabric-react/lib/TextField";
|
||||||
import { Link } from "office-ui-fabric-react/lib/Link";
|
import { Link } from "office-ui-fabric-react/lib/Link";
|
||||||
import { ChoiceGroup, FontIcon, IChoiceGroupProps } from "office-ui-fabric-react";
|
import {
|
||||||
|
ChoiceGroup,
|
||||||
|
FontIcon,
|
||||||
|
IChoiceGroupProps,
|
||||||
|
IProgressIndicatorProps,
|
||||||
|
ProgressIndicator,
|
||||||
|
} from "office-ui-fabric-react";
|
||||||
|
|
||||||
export interface TextFieldProps extends ITextFieldProps {
|
export interface TextFieldProps extends ITextFieldProps {
|
||||||
label: string;
|
label: string;
|
||||||
@ -27,6 +33,7 @@ export interface DialogProps {
|
|||||||
choiceGroupProps?: IChoiceGroupProps;
|
choiceGroupProps?: IChoiceGroupProps;
|
||||||
textFieldProps?: TextFieldProps;
|
textFieldProps?: TextFieldProps;
|
||||||
linkProps?: LinkProps;
|
linkProps?: LinkProps;
|
||||||
|
progressIndicatorProps?: IProgressIndicatorProps;
|
||||||
primaryButtonText: string;
|
primaryButtonText: string;
|
||||||
secondaryButtonText: string;
|
secondaryButtonText: string;
|
||||||
onPrimaryButtonClick: () => void;
|
onPrimaryButtonClick: () => void;
|
||||||
@ -69,6 +76,7 @@ export class DialogComponent extends React.Component<DialogProps, {}> {
|
|||||||
const choiceGroupProps: IChoiceGroupProps = this.props.choiceGroupProps;
|
const choiceGroupProps: IChoiceGroupProps = this.props.choiceGroupProps;
|
||||||
const textFieldProps: ITextFieldProps = this.props.textFieldProps;
|
const textFieldProps: ITextFieldProps = this.props.textFieldProps;
|
||||||
const linkProps: LinkProps = this.props.linkProps;
|
const linkProps: LinkProps = this.props.linkProps;
|
||||||
|
const progressIndicatorProps: IProgressIndicatorProps = this.props.progressIndicatorProps;
|
||||||
const primaryButtonProps: IButtonProps = {
|
const primaryButtonProps: IButtonProps = {
|
||||||
text: this.props.primaryButtonText,
|
text: this.props.primaryButtonText,
|
||||||
disabled: this.props.primaryButtonDisabled || false,
|
disabled: this.props.primaryButtonDisabled || false,
|
||||||
@ -91,6 +99,7 @@ export class DialogComponent extends React.Component<DialogProps, {}> {
|
|||||||
{linkProps.linkText} <FontIcon iconName="NavigateExternalInline" />
|
{linkProps.linkText} <FontIcon iconName="NavigateExternalInline" />
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
{progressIndicatorProps && <ProgressIndicator {...progressIndicatorProps} />}
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<PrimaryButton {...primaryButtonProps} />
|
<PrimaryButton {...primaryButtonProps} />
|
||||||
{secondaryButtonProps && <DefaultButton {...secondaryButtonProps} />}
|
{secondaryButtonProps && <DefaultButton {...secondaryButtonProps} />}
|
||||||
|
@ -127,7 +127,7 @@ export class GalleryCardComponent extends React.Component<GalleryCardComponentPr
|
|||||||
{this.props.isFavorite !== undefined &&
|
{this.props.isFavorite !== undefined &&
|
||||||
this.generateIconButtonWithTooltip(
|
this.generateIconButtonWithTooltip(
|
||||||
this.props.isFavorite ? "HeartFill" : "Heart",
|
this.props.isFavorite ? "HeartFill" : "Heart",
|
||||||
this.props.isFavorite ? "Unlike" : "Like",
|
this.props.isFavorite ? "Unfavorite" : "Favorite",
|
||||||
"left",
|
"left",
|
||||||
this.props.isFavorite ? this.props.onUnfavoriteClick : this.props.onFavoriteClick
|
this.props.isFavorite ? this.props.onUnfavoriteClick : this.props.onFavoriteClick
|
||||||
)}
|
)}
|
||||||
|
@ -185,7 +185,7 @@ exports[`GalleryCardComponent renders 1`] = `
|
|||||||
"gapSpace": 0,
|
"gapSpace": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content="Like"
|
content="Favorite"
|
||||||
id="TooltipHost-IconButton-Heart"
|
id="TooltipHost-IconButton-Heart"
|
||||||
styles={
|
styles={
|
||||||
Object {
|
Object {
|
||||||
@ -197,14 +197,14 @@ exports[`GalleryCardComponent renders 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<CustomizedIconButton
|
<CustomizedIconButton
|
||||||
ariaLabel="Like"
|
ariaLabel="Favorite"
|
||||||
iconProps={
|
iconProps={
|
||||||
Object {
|
Object {
|
||||||
"iconName": "Heart",
|
"iconName": "Heart",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
title="Like"
|
title="Favorite"
|
||||||
/>
|
/>
|
||||||
</StyledTooltipHostBase>
|
</StyledTooltipHostBase>
|
||||||
<StyledTooltipHostBase
|
<StyledTooltipHostBase
|
||||||
|
@ -7,14 +7,20 @@ import {
|
|||||||
} from "./GalleryAndNotebookViewerComponent";
|
} from "./GalleryAndNotebookViewerComponent";
|
||||||
|
|
||||||
export class GalleryAndNotebookViewerComponentAdapter implements ReactAdapter {
|
export class GalleryAndNotebookViewerComponentAdapter implements ReactAdapter {
|
||||||
|
private key: string;
|
||||||
public parameters: ko.Observable<number>;
|
public parameters: ko.Observable<number>;
|
||||||
|
|
||||||
constructor(private props: GalleryAndNotebookViewerComponentProps) {
|
constructor(private props: GalleryAndNotebookViewerComponentProps) {
|
||||||
|
this.reset();
|
||||||
this.parameters = ko.observable<number>(Date.now());
|
this.parameters = ko.observable<number>(Date.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderComponent(): JSX.Element {
|
public renderComponent(): JSX.Element {
|
||||||
return <GalleryAndNotebookViewerComponent {...this.props} />;
|
return <GalleryAndNotebookViewerComponent key={this.key} {...this.props} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
public reset(): void {
|
||||||
|
this.key = `GalleryAndNotebookViewerComponent-${Date.now()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public triggerRender(): void {
|
public triggerRender(): void {
|
||||||
|
@ -7,3 +7,12 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
font-family: @DataExplorerFont;
|
font-family: @DataExplorerFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.publicGalleryTabContainer {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publicGalleryTabOverlayContent {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
IRectangle,
|
IRectangle,
|
||||||
Label,
|
Label,
|
||||||
List,
|
List,
|
||||||
|
Overlay,
|
||||||
Pivot,
|
Pivot,
|
||||||
PivotItem,
|
PivotItem,
|
||||||
SearchBox,
|
SearchBox,
|
||||||
@ -74,14 +75,14 @@ interface GalleryTabInfo {
|
|||||||
export class GalleryViewerComponent extends React.Component<GalleryViewerComponentProps, GalleryViewerComponentState> {
|
export class GalleryViewerComponent extends React.Component<GalleryViewerComponentProps, GalleryViewerComponentState> {
|
||||||
public static readonly OfficialSamplesTitle = "Official samples";
|
public static readonly OfficialSamplesTitle = "Official samples";
|
||||||
public static readonly PublicGalleryTitle = "Public gallery";
|
public static readonly PublicGalleryTitle = "Public gallery";
|
||||||
public static readonly FavoritesTitle = "Liked";
|
public static readonly FavoritesTitle = "My favorites";
|
||||||
public static readonly PublishedTitle = "Your published work";
|
public static readonly PublishedTitle = "My published work";
|
||||||
|
|
||||||
private static readonly rowsPerPage = 5;
|
private static readonly rowsPerPage = 5;
|
||||||
|
|
||||||
private static readonly mostViewedText = "Most viewed";
|
private static readonly mostViewedText = "Most viewed";
|
||||||
private static readonly mostDownloadedText = "Most downloaded";
|
private static readonly mostDownloadedText = "Most downloaded";
|
||||||
private static readonly mostFavoritedText = "Most liked";
|
private static readonly mostFavoritedText = "Most favorited";
|
||||||
private static readonly mostRecentText = "Most recent";
|
private static readonly mostRecentText = "Most recent";
|
||||||
|
|
||||||
private readonly sortingOptions: IDropdownOption[];
|
private readonly sortingOptions: IDropdownOption[];
|
||||||
@ -222,8 +223,8 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
|||||||
content: this.isEmptyData(data)
|
content: this.isEmptyData(data)
|
||||||
? this.createEmptyTabContent(
|
? this.createEmptyTabContent(
|
||||||
"ContactHeart",
|
"ContactHeart",
|
||||||
"You have not liked anything",
|
"You have not favorited anything",
|
||||||
"Like any notebook from Official Samples or Public gallery"
|
"Favorite any notebook from Official samples or Public gallery"
|
||||||
)
|
)
|
||||||
: this.createSearchBarHeader(this.createCardsTabContent(data)),
|
: this.createSearchBarHeader(this.createCardsTabContent(data)),
|
||||||
};
|
};
|
||||||
@ -245,7 +246,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
|||||||
private createPublishedNotebooksTabContent = (data: IGalleryItem[]): JSX.Element => {
|
private createPublishedNotebooksTabContent = (data: IGalleryItem[]): JSX.Element => {
|
||||||
const { published, underReview, removed } = GalleryUtils.filterPublishedNotebooks(data);
|
const { published, underReview, removed } = GalleryUtils.filterPublishedNotebooks(data);
|
||||||
const content = (
|
const content = (
|
||||||
<Stack tokens={{ childrenGap: 10 }}>
|
<Stack tokens={{ childrenGap: 20 }}>
|
||||||
{published?.length > 0 &&
|
{published?.length > 0 &&
|
||||||
this.createPublishedNotebooksSectionContent(
|
this.createPublishedNotebooksSectionContent(
|
||||||
undefined,
|
undefined,
|
||||||
@ -276,7 +277,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
|||||||
content: JSX.Element
|
content: JSX.Element
|
||||||
): JSX.Element => {
|
): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Stack tokens={{ childrenGap: 5 }}>
|
<Stack tokens={{ childrenGap: 10 }}>
|
||||||
{title && <Text styles={{ root: { fontWeight: FontWeights.semibold } }}>{title}</Text>}
|
{title && <Text styles={{ root: { fontWeight: FontWeights.semibold } }}>{title}</Text>}
|
||||||
{description && <Text>{description}</Text>}
|
{description && <Text>{description}</Text>}
|
||||||
{content}
|
{content}
|
||||||
@ -285,15 +286,22 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
|||||||
};
|
};
|
||||||
|
|
||||||
private createPublicGalleryTabContent(data: IGalleryItem[], acceptedCodeOfConduct: boolean): JSX.Element {
|
private createPublicGalleryTabContent(data: IGalleryItem[], acceptedCodeOfConduct: boolean): JSX.Element {
|
||||||
return acceptedCodeOfConduct === false ? (
|
return (
|
||||||
<CodeOfConductComponent
|
<div className="publicGalleryTabContainer">
|
||||||
junoClient={this.props.junoClient}
|
{this.createSearchBarHeader(this.createCardsTabContent(data))}
|
||||||
onAcceptCodeOfConduct={(result: boolean) => {
|
{acceptedCodeOfConduct === false && (
|
||||||
this.setState({ isCodeOfConductAccepted: result });
|
<Overlay isDarkThemed>
|
||||||
}}
|
<div className="publicGalleryTabOverlayContent">
|
||||||
/>
|
<CodeOfConductComponent
|
||||||
) : (
|
junoClient={this.props.junoClient}
|
||||||
this.createSearchBarHeader(this.createCardsTabContent(data))
|
onAcceptCodeOfConduct={(result: boolean) => {
|
||||||
|
this.setState({ isCodeOfConductAccepted: result });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Overlay>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,14 +3,11 @@
|
|||||||
*/
|
*/
|
||||||
import { Notebook } from "@nteract/commutable";
|
import { Notebook } from "@nteract/commutable";
|
||||||
import { createContentRef } from "@nteract/core";
|
import { createContentRef } from "@nteract/core";
|
||||||
import { IChoiceGroupProps, Icon, Link, ProgressIndicator } from "office-ui-fabric-react";
|
import { IChoiceGroupProps, Icon, IProgressIndicatorProps, Link, ProgressIndicator } from "office-ui-fabric-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { contents } from "rx-jupyter";
|
import { contents } from "rx-jupyter";
|
||||||
import * as Logger from "../../../Common/Logger";
|
|
||||||
import { IGalleryItem, JunoClient } from "../../../Juno/JunoClient";
|
import { IGalleryItem, JunoClient } from "../../../Juno/JunoClient";
|
||||||
import * as GalleryUtils from "../../../Utils/GalleryUtils";
|
import * as GalleryUtils from "../../../Utils/GalleryUtils";
|
||||||
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
|
|
||||||
import { ConsoleDataType } from "../../Menus/NotificationConsole/NotificationConsoleComponent";
|
|
||||||
import { NotebookClientV2 } from "../../Notebook/NotebookClientV2";
|
import { NotebookClientV2 } from "../../Notebook/NotebookClientV2";
|
||||||
import { NotebookComponentBootstrapper } from "../../Notebook/NotebookComponent/NotebookComponentBootstrapper";
|
import { NotebookComponentBootstrapper } from "../../Notebook/NotebookComponent/NotebookComponentBootstrapper";
|
||||||
import NotebookReadOnlyRenderer from "../../Notebook/NotebookRenderer/NotebookReadOnlyRenderer";
|
import NotebookReadOnlyRenderer from "../../Notebook/NotebookRenderer/NotebookReadOnlyRenderer";
|
||||||
@ -21,7 +18,7 @@ import Explorer from "../../Explorer";
|
|||||||
import { NotebookV4 } from "@nteract/commutable/lib/v4";
|
import { NotebookV4 } from "@nteract/commutable/lib/v4";
|
||||||
import { SessionStorageUtility } from "../../../Shared/StorageUtility";
|
import { SessionStorageUtility } from "../../../Shared/StorageUtility";
|
||||||
import { DialogHost } from "../../../Utils/GalleryUtils";
|
import { DialogHost } from "../../../Utils/GalleryUtils";
|
||||||
import { getErrorMessage, handleError } from "../../../Common/ErrorHandlingUtils";
|
import { handleError } from "../../../Common/ErrorHandlingUtils";
|
||||||
|
|
||||||
export interface NotebookViewerComponentProps {
|
export interface NotebookViewerComponentProps {
|
||||||
container?: Explorer;
|
container?: Explorer;
|
||||||
@ -178,6 +175,32 @@ export class NotebookViewerComponent
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DialogHost
|
||||||
|
showOkModalDialog(
|
||||||
|
title: string,
|
||||||
|
msg: string,
|
||||||
|
okLabel: string,
|
||||||
|
onOk: () => void,
|
||||||
|
progressIndicatorProps?: IProgressIndicatorProps
|
||||||
|
): void {
|
||||||
|
this.setState({
|
||||||
|
dialogProps: {
|
||||||
|
isModal: true,
|
||||||
|
visible: true,
|
||||||
|
title,
|
||||||
|
subText: msg,
|
||||||
|
primaryButtonText: okLabel,
|
||||||
|
onPrimaryButtonClick: () => {
|
||||||
|
this.setState({ dialogProps: undefined });
|
||||||
|
onOk && onOk();
|
||||||
|
},
|
||||||
|
secondaryButtonText: undefined,
|
||||||
|
onSecondaryButtonClick: undefined,
|
||||||
|
progressIndicatorProps,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// DialogHost
|
// DialogHost
|
||||||
showOkCancelModalDialog(
|
showOkCancelModalDialog(
|
||||||
title: string,
|
title: string,
|
||||||
@ -186,8 +209,10 @@ export class NotebookViewerComponent
|
|||||||
onOk: () => void,
|
onOk: () => void,
|
||||||
cancelLabel: string,
|
cancelLabel: string,
|
||||||
onCancel: () => void,
|
onCancel: () => void,
|
||||||
|
progressIndicatorProps?: IProgressIndicatorProps,
|
||||||
choiceGroupProps?: IChoiceGroupProps,
|
choiceGroupProps?: IChoiceGroupProps,
|
||||||
textFieldProps?: TextFieldProps
|
textFieldProps?: TextFieldProps,
|
||||||
|
primaryButtonDisabled?: boolean
|
||||||
): void {
|
): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
dialogProps: {
|
dialogProps: {
|
||||||
@ -205,8 +230,10 @@ export class NotebookViewerComponent
|
|||||||
this.setState({ dialogProps: undefined });
|
this.setState({ dialogProps: undefined });
|
||||||
onCancel && onCancel();
|
onCancel && onCancel();
|
||||||
},
|
},
|
||||||
|
progressIndicatorProps,
|
||||||
choiceGroupProps,
|
choiceGroupProps,
|
||||||
textFieldProps,
|
textFieldProps,
|
||||||
|
primaryButtonDisabled,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,7 @@ import { appInsights } from "../Shared/appInsights";
|
|||||||
import { SelfServeLoadingComponentAdapter } from "../SelfServe/SelfServeLoadingComponentAdapter";
|
import { SelfServeLoadingComponentAdapter } from "../SelfServe/SelfServeLoadingComponentAdapter";
|
||||||
import { SelfServeType } from "../SelfServe/SelfServeUtils";
|
import { SelfServeType } from "../SelfServe/SelfServeUtils";
|
||||||
import { SelfServeComponentAdapter } from "../SelfServe/SelfServeComponentAdapter";
|
import { SelfServeComponentAdapter } from "../SelfServe/SelfServeComponentAdapter";
|
||||||
|
import { GalleryTab } from "./Controls/NotebookGallery/GalleryViewerComponent";
|
||||||
|
|
||||||
BindingHandlersRegisterer.registerBindingHandlers();
|
BindingHandlersRegisterer.registerBindingHandlers();
|
||||||
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
|
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
|
||||||
@ -2810,10 +2811,36 @@ export default class Explorer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async openGallery(notebookUrl?: string, galleryItem?: IGalleryItem, isFavorite?: boolean) {
|
public async openGallery(
|
||||||
|
selectedTab?: GalleryTab,
|
||||||
|
notebookUrl?: string,
|
||||||
|
galleryItem?: IGalleryItem,
|
||||||
|
isFavorite?: boolean
|
||||||
|
) {
|
||||||
let title: string = "Gallery";
|
let title: string = "Gallery";
|
||||||
let hashLocation: string = "gallery";
|
let hashLocation: string = "gallery";
|
||||||
|
|
||||||
|
const galleryTabOptions: any = {
|
||||||
|
// GalleryTabOptions
|
||||||
|
account: userContext.databaseAccount,
|
||||||
|
container: this,
|
||||||
|
junoClient: this.notebookManager?.junoClient,
|
||||||
|
selectedTab: selectedTab || GalleryTab.OfficialSamples,
|
||||||
|
notebookUrl,
|
||||||
|
galleryItem,
|
||||||
|
isFavorite,
|
||||||
|
// TabOptions
|
||||||
|
tabKind: ViewModels.CollectionTabKind.Gallery,
|
||||||
|
title: title,
|
||||||
|
tabPath: title,
|
||||||
|
documentClientUtility: null,
|
||||||
|
isActive: ko.observable(false),
|
||||||
|
hashLocation: hashLocation,
|
||||||
|
onUpdateTabsButtons: this.onUpdateTabsButtons,
|
||||||
|
isTabsContentExpanded: ko.observable(true),
|
||||||
|
onLoadStartKey: null,
|
||||||
|
};
|
||||||
|
|
||||||
const galleryTabs = this.tabsManager.getTabs(
|
const galleryTabs = this.tabsManager.getTabs(
|
||||||
ViewModels.CollectionTabKind.Gallery,
|
ViewModels.CollectionTabKind.Gallery,
|
||||||
(tab) => tab.hashLocation() == hashLocation
|
(tab) => tab.hashLocation() == hashLocation
|
||||||
@ -2822,31 +2849,12 @@ export default class Explorer {
|
|||||||
|
|
||||||
if (galleryTab) {
|
if (galleryTab) {
|
||||||
this.tabsManager.activateTab(galleryTab);
|
this.tabsManager.activateTab(galleryTab);
|
||||||
|
(galleryTab as any).reset(galleryTabOptions);
|
||||||
} else {
|
} else {
|
||||||
if (!this.galleryTab) {
|
if (!this.galleryTab) {
|
||||||
this.galleryTab = await import(/* webpackChunkName: "GalleryTab" */ "./Tabs/GalleryTab");
|
this.galleryTab = await import(/* webpackChunkName: "GalleryTab" */ "./Tabs/GalleryTab");
|
||||||
}
|
}
|
||||||
|
const newTab = new this.galleryTab.default(galleryTabOptions);
|
||||||
const newTab = new this.galleryTab.default({
|
|
||||||
// GalleryTabOptions
|
|
||||||
account: userContext.databaseAccount,
|
|
||||||
container: this,
|
|
||||||
junoClient: this.notebookManager?.junoClient,
|
|
||||||
notebookUrl,
|
|
||||||
galleryItem,
|
|
||||||
isFavorite,
|
|
||||||
// TabOptions
|
|
||||||
tabKind: ViewModels.CollectionTabKind.Gallery,
|
|
||||||
title: title,
|
|
||||||
tabPath: title,
|
|
||||||
documentClientUtility: null,
|
|
||||||
isActive: ko.observable(false),
|
|
||||||
hashLocation: hashLocation,
|
|
||||||
onUpdateTabsButtons: this.onUpdateTabsButtons,
|
|
||||||
isTabsContentExpanded: ko.observable(true),
|
|
||||||
onLoadStartKey: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.tabsManager.activateNewTab(newTab);
|
this.tabsManager.activateNewTab(newTab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { toJS } from "@nteract/commutable";
|
|||||||
import { CodeOfConductComponent } from "../Controls/NotebookGallery/CodeOfConductComponent";
|
import { CodeOfConductComponent } from "../Controls/NotebookGallery/CodeOfConductComponent";
|
||||||
import { HttpStatusCodes } from "../../Common/Constants";
|
import { HttpStatusCodes } from "../../Common/Constants";
|
||||||
import { handleError, getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
import { handleError, getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||||
|
import { GalleryTab } from "../Controls/NotebookGallery/GalleryViewerComponent";
|
||||||
|
|
||||||
export class PublishNotebookPaneAdapter implements ReactAdapter {
|
export class PublishNotebookPaneAdapter implements ReactAdapter {
|
||||||
parameters: ko.Observable<number>;
|
parameters: ko.Observable<number>;
|
||||||
@ -163,6 +164,7 @@ export class PublishNotebookPaneAdapter implements ReactAdapter {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
NotificationConsoleUtils.logConsoleInfo(`Published ${this.name} to gallery`);
|
NotificationConsoleUtils.logConsoleInfo(`Published ${this.name} to gallery`);
|
||||||
|
this.container.openGallery(GalleryTab.Published);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -172,11 +172,12 @@ export class PublishNotebookPaneComponent extends React.Component<PublishNoteboo
|
|||||||
this.nameProps = {
|
this.nameProps = {
|
||||||
label: "Name",
|
label: "Name",
|
||||||
ariaLabel: "Name",
|
ariaLabel: "Name",
|
||||||
defaultValue: this.props.notebookName,
|
defaultValue: FileSystemUtil.stripExtension(this.props.notebookName, "ipynb"),
|
||||||
required: true,
|
required: true,
|
||||||
onChange: (event, newValue) => {
|
onChange: (event, newValue) => {
|
||||||
this.props.onChangeName(newValue);
|
const notebookName = newValue + ".ipynb";
|
||||||
this.setState({ notebookName: newValue });
|
this.props.onChangeName(notebookName);
|
||||||
|
this.setState({ notebookName });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ exports[`PublishNotebookPaneComponent renders 1`] = `
|
|||||||
<StackItem>
|
<StackItem>
|
||||||
<StyledTextFieldBase
|
<StyledTextFieldBase
|
||||||
ariaLabel="Name"
|
ariaLabel="Name"
|
||||||
defaultValue="SampleNotebook.ipynb"
|
defaultValue="SampleNotebook"
|
||||||
label="Name"
|
label="Name"
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
required={true}
|
required={true}
|
||||||
|
@ -11,6 +11,7 @@ interface GalleryTabOptions extends ViewModels.TabOptions {
|
|||||||
account: DatabaseAccount;
|
account: DatabaseAccount;
|
||||||
container: Explorer;
|
container: Explorer;
|
||||||
junoClient: JunoClient;
|
junoClient: JunoClient;
|
||||||
|
selectedTab: GalleryViewerTab;
|
||||||
notebookUrl?: string;
|
notebookUrl?: string;
|
||||||
galleryItem?: IGalleryItem;
|
galleryItem?: IGalleryItem;
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
@ -21,24 +22,42 @@ interface GalleryTabOptions extends ViewModels.TabOptions {
|
|||||||
*/
|
*/
|
||||||
export default class GalleryTab extends TabsBase {
|
export default class GalleryTab extends TabsBase {
|
||||||
private container: Explorer;
|
private container: Explorer;
|
||||||
|
private galleryAndNotebookViewerComponentProps: GalleryAndNotebookViewerComponentProps;
|
||||||
public galleryAndNotebookViewerComponentAdapter: GalleryAndNotebookViewerComponentAdapter;
|
public galleryAndNotebookViewerComponentAdapter: GalleryAndNotebookViewerComponentAdapter;
|
||||||
|
|
||||||
constructor(options: GalleryTabOptions) {
|
constructor(options: GalleryTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.container = options.container;
|
this.container = options.container;
|
||||||
const props: GalleryAndNotebookViewerComponentProps = {
|
|
||||||
|
this.galleryAndNotebookViewerComponentProps = {
|
||||||
container: options.container,
|
container: options.container,
|
||||||
junoClient: options.junoClient,
|
junoClient: options.junoClient,
|
||||||
notebookUrl: options.notebookUrl,
|
notebookUrl: options.notebookUrl,
|
||||||
galleryItem: options.galleryItem,
|
galleryItem: options.galleryItem,
|
||||||
isFavorite: options.isFavorite,
|
isFavorite: options.isFavorite,
|
||||||
selectedTab: GalleryViewerTab.OfficialSamples,
|
selectedTab: options.selectedTab,
|
||||||
sortBy: SortBy.MostViewed,
|
sortBy: SortBy.MostViewed,
|
||||||
searchText: undefined,
|
searchText: undefined,
|
||||||
};
|
};
|
||||||
|
this.galleryAndNotebookViewerComponentAdapter = new GalleryAndNotebookViewerComponentAdapter(
|
||||||
|
this.galleryAndNotebookViewerComponentProps
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.galleryAndNotebookViewerComponentAdapter = new GalleryAndNotebookViewerComponentAdapter(props);
|
public reset(options: GalleryTabOptions) {
|
||||||
|
this.container = options.container;
|
||||||
|
|
||||||
|
this.galleryAndNotebookViewerComponentProps.container = options.container;
|
||||||
|
this.galleryAndNotebookViewerComponentProps.junoClient = options.junoClient;
|
||||||
|
this.galleryAndNotebookViewerComponentProps.notebookUrl = options.notebookUrl;
|
||||||
|
this.galleryAndNotebookViewerComponentProps.galleryItem = options.galleryItem;
|
||||||
|
this.galleryAndNotebookViewerComponentProps.isFavorite = options.isFavorite;
|
||||||
|
this.galleryAndNotebookViewerComponentProps.selectedTab = options.selectedTab;
|
||||||
|
this.galleryAndNotebookViewerComponentProps.sortBy = SortBy.MostViewed;
|
||||||
|
this.galleryAndNotebookViewerComponentProps.searchText = undefined;
|
||||||
|
|
||||||
|
this.galleryAndNotebookViewerComponentAdapter.reset();
|
||||||
|
this.galleryAndNotebookViewerComponentAdapter.triggerRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getContainer(): Explorer {
|
protected getContainer(): Explorer {
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
GalleryViewerComponent,
|
GalleryViewerComponent,
|
||||||
} from "../Explorer/Controls/NotebookGallery/GalleryViewerComponent";
|
} from "../Explorer/Controls/NotebookGallery/GalleryViewerComponent";
|
||||||
import Explorer from "../Explorer/Explorer";
|
import Explorer from "../Explorer/Explorer";
|
||||||
import { IChoiceGroupOption, IChoiceGroupProps } from "office-ui-fabric-react";
|
import { IChoiceGroupOption, IChoiceGroupProps, IProgressIndicatorProps } from "office-ui-fabric-react";
|
||||||
import { TextFieldProps } from "../Explorer/Controls/DialogReactComponent/DialogComponent";
|
import { TextFieldProps } from "../Explorer/Controls/DialogReactComponent/DialogComponent";
|
||||||
import { handleError } from "../Common/ErrorHandlingUtils";
|
import { handleError } from "../Common/ErrorHandlingUtils";
|
||||||
import { HttpStatusCodes } from "../Common/Constants";
|
import { HttpStatusCodes } from "../Common/Constants";
|
||||||
@ -81,6 +81,14 @@ export interface GalleryViewerProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DialogHost {
|
export interface DialogHost {
|
||||||
|
showOkModalDialog(
|
||||||
|
title: string,
|
||||||
|
msg: string,
|
||||||
|
okLabel: string,
|
||||||
|
onOk: () => void,
|
||||||
|
progressIndicatorProps?: IProgressIndicatorProps
|
||||||
|
): void;
|
||||||
|
|
||||||
showOkCancelModalDialog(
|
showOkCancelModalDialog(
|
||||||
title: string,
|
title: string,
|
||||||
msg: string,
|
msg: string,
|
||||||
@ -88,8 +96,10 @@ export interface DialogHost {
|
|||||||
onOk: () => void,
|
onOk: () => void,
|
||||||
cancelLabel: string,
|
cancelLabel: string,
|
||||||
onCancel: () => void,
|
onCancel: () => void,
|
||||||
|
progressIndicatorProps?: IProgressIndicatorProps,
|
||||||
choiceGroupProps?: IChoiceGroupProps,
|
choiceGroupProps?: IChoiceGroupProps,
|
||||||
textFieldProps?: TextFieldProps
|
textFieldProps?: TextFieldProps,
|
||||||
|
primaryButtonDisabled?: boolean
|
||||||
): void;
|
): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,8 +118,17 @@ export function reportAbuse(
|
|||||||
undefined,
|
undefined,
|
||||||
"Report Abuse",
|
"Report Abuse",
|
||||||
async () => {
|
async () => {
|
||||||
const clearSubmitReportNotification = NotificationConsoleUtils.logConsoleProgress(
|
dialogHost.showOkCancelModalDialog(
|
||||||
`Submitting your report on ${data.name} violating code of conduct`
|
"Report Abuse",
|
||||||
|
`Submitting your report on ${data.name} violating code of conduct`,
|
||||||
|
"Reporting...",
|
||||||
|
undefined,
|
||||||
|
"Cancel",
|
||||||
|
undefined,
|
||||||
|
{},
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -118,9 +137,16 @@ export function reportAbuse(
|
|||||||
throw new Error(`Received HTTP ${response.status} when submitting report for ${data.name}`);
|
throw new Error(`Received HTTP ${response.status} when submitting report for ${data.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationConsoleUtils.logConsoleInfo(
|
dialogHost.showOkModalDialog(
|
||||||
`Your report on ${data.name} has been submitted. Thank you for reporting the violation.`
|
"Report Abuse",
|
||||||
|
`Your report on ${data.name} has been submitted. Thank you for reporting the violation.`,
|
||||||
|
"OK",
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
percentComplete: 1,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onComplete(response.data);
|
onComplete(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(
|
handleError(
|
||||||
@ -128,12 +154,21 @@ export function reportAbuse(
|
|||||||
"GalleryUtils/reportAbuse",
|
"GalleryUtils/reportAbuse",
|
||||||
`Failed to submit report on ${data.name} violating code of conduct`
|
`Failed to submit report on ${data.name} violating code of conduct`
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
clearSubmitReportNotification();
|
dialogHost.showOkModalDialog(
|
||||||
|
"Report Abuse",
|
||||||
|
`Failed to submit report on ${data.name} violating code of conduct`,
|
||||||
|
"OK",
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
percentComplete: 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Cancel",
|
"Cancel",
|
||||||
undefined,
|
undefined,
|
||||||
|
undefined,
|
||||||
{
|
{
|
||||||
label: "How does this content violate the code of conduct?",
|
label: "How does this content violate the code of conduct?",
|
||||||
options: abuseCategories,
|
options: abuseCategories,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user