From 3db6276f48f29cb6423025fcd80cf02e9691ad41 Mon Sep 17 00:00:00 2001 From: Sweatha Viswanathan Date: Thu, 19 Nov 2020 18:32:52 -0800 Subject: [PATCH] recommendations prototype --- src/Explorer/Explorer.ts | 9 +- .../RecommendationsAdapter.tsx | 50 +++++++++++ .../RecommendationsComponent.tsx | 89 +++++++++++++++++++ src/Explorer/Recommendations/api.ts | 10 +++ src/Juno/JunoClient.ts | 19 ++++ src/explorer.html | 5 ++ webpack.config.js | 2 +- 7 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 src/Explorer/Recommendations/RecommendationsAdapter.tsx create mode 100644 src/Explorer/Recommendations/RecommendationsComponent.tsx create mode 100644 src/Explorer/Recommendations/api.ts diff --git a/src/Explorer/Explorer.ts b/src/Explorer/Explorer.ts index 536702a84..2f0f4f77f 100644 --- a/src/Explorer/Explorer.ts +++ b/src/Explorer/Explorer.ts @@ -37,6 +37,7 @@ import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer import { BrowseQueriesPane } from "./Panes/BrowseQueriesPane"; import { CassandraAPIDataClient, TableDataClient, TablesAPIDataClient } from "./Tables/TableDataClient"; import { CommandBarComponentAdapter } from "./Menus/CommandBar/CommandBarComponentAdapter"; +import { RecommendationsAdapter } from "./Recommendations/RecommendationsAdapter"; import { configContext, Platform, updateConfigContext } from "../ConfigContext"; import { ConsoleData, ConsoleDataType } from "./Menus/NotificationConsole/NotificationConsoleComponent"; import { decryptJWTToken, getAuthorizationHeader } from "../Utils/AuthorizationUtils"; @@ -207,6 +208,7 @@ export default class Explorer { public isLinkInjectionEnabled: ko.Computed; public isSettingsV2Enabled: ko.Observable; public isGitHubPaneEnabled: ko.Observable; + public isRecosEnabled: ko.Observable; public isPublishNotebookPaneEnabled: ko.Observable; public isCopyNotebookPaneEnabled: ko.Observable; public isHostedDataExplorerEnabled: ko.Computed; @@ -261,6 +263,7 @@ export default class Explorer { private _dialogProps: ko.Observable; private addSynapseLinkDialog: DialogComponentAdapter; private _addSynapseLinkDialogProps: ko.Observable; + private recommendationsAdapter: RecommendationsAdapter private static readonly MaxNbDatabasesToAutoExpand = 5; @@ -415,6 +418,7 @@ export default class Explorer { //this.isSettingsV2Enabled = ko.computed(() => this.isFeatureEnabled(Constants.Features.enableSettingsV2)); this.isSettingsV2Enabled = ko.observable(false); this.isGitHubPaneEnabled = ko.observable(false); + this.isRecosEnabled = ko.observable(false); this.isPublishNotebookPaneEnabled = ko.observable(false); this.isCopyNotebookPaneEnabled = ko.observable(false); @@ -888,7 +892,7 @@ export default class Explorer { this.commandBarComponentAdapter = new CommandBarComponentAdapter(this); this.notificationConsoleComponentAdapter = new NotificationConsoleComponentAdapter(this); - + this._initSettings(); TelemetryProcessor.traceSuccess( @@ -915,6 +919,7 @@ export default class Explorer { this.gitHubReposPane = this.notebookManager.gitHubReposPane; this.isGitHubPaneEnabled(true); + this.isRecosEnabled(true); } this.refreshCommandBarButtons(); @@ -1001,6 +1006,8 @@ export default class Explorer { }); this.addSynapseLinkDialog = new DialogComponentAdapter(); this.addSynapseLinkDialog.parameters = this._addSynapseLinkDialogProps; + this.recommendationsAdapter = new RecommendationsAdapter(this); + } public openEnableSynapseLinkDialog(): void { diff --git a/src/Explorer/Recommendations/RecommendationsAdapter.tsx b/src/Explorer/Recommendations/RecommendationsAdapter.tsx new file mode 100644 index 000000000..ab0ff1e35 --- /dev/null +++ b/src/Explorer/Recommendations/RecommendationsAdapter.tsx @@ -0,0 +1,50 @@ +/** + * This adapter is responsible to render the React component + * If the component signals a change through the callback passed in the properties, it must render the React component when appropriate + * and update any knockout observables passed from the parent. + */ +import * as ko from "knockout"; +import * as React from "react"; +import { ReactAdapter } from "../../Bindings/ReactBindingHandler"; +import * as ViewModels from "../../Contracts/ViewModels"; +import { MessageBar, MessageBarType, Text} from "office-ui-fabric-react"; +import { StyleConstants } from "../../Common/Constants"; +import Explorer from "../Explorer"; +// import {getRecommendations} from "./api"; +import { configContext } from "../../ConfigContext"; +import { JunoClient } from "../../Juno/JunoClient"; +import { ICardTokens, Card } from "@uifabric/react-cards"; +import {Recommendations, RecommendationProps} from "./RecommendationsComponent"; +// import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; + +export class RecommendationsAdapter implements ReactAdapter { +public parameters: ko.Observable; + public container: Explorer; + + + + constructor(container: Explorer) { + this.container = container; + this.parameters = ko.observable(Date.now()); + + } + + public forceRender(): void { + window.requestAnimationFrame(() => this.parameters(Date.now())); + } + + public renderComponent(): JSX.Element { + //const backgroundColor = StyleConstants.BaseLight; + + + return ( + + ); + } + + public triggerRender(): void { + window.requestAnimationFrame(() => this.parameters(Date.now())); + } + + +} diff --git a/src/Explorer/Recommendations/RecommendationsComponent.tsx b/src/Explorer/Recommendations/RecommendationsComponent.tsx new file mode 100644 index 000000000..57ce34727 --- /dev/null +++ b/src/Explorer/Recommendations/RecommendationsComponent.tsx @@ -0,0 +1,89 @@ +import { ICardTokens, Card } from "@uifabric/react-cards"; +import React from "react"; +import { JunoClient } from "../../Juno/JunoClient"; +import Explorer from "../Explorer"; +import { MessageBar, MessageBarButton, MessageBarType, IMessageBarStyles, Spinner } from "office-ui-fabric-react"; +import { FontSize } from "../Controls/GitHub/GitHubStyleConstants"; + +export interface RecommendationProps { + explorer: Explorer; + + } + + export const recoStyles: Partial = { root: { backgroundColor: "#0078d4" , + color:"white", fontSize: "16px"}, text: {fontSize: "16px"}, icon: {display: "none"}}; + + export const recoButtonStyles = {root: {fontSize: "10px"}}; + +export class Recommendations extends React.Component { + + public state: { recoMessage: string; loadingInfo: boolean;}; + container: Explorer; + + + constructor(props: RecommendationProps) { + super(props); + //this.container = this.container; + this.state = { + recoMessage:"", + loadingInfo: false + } + this.loadInfo(); + } + + private async loadInfo(){ + this.setState({loadingInfo: true}); + let junoClient = new JunoClient(this.props.explorer.databaseAccount); + + let resp = await junoClient.getRecos(); + // this.state.recoMessage = resp.description; + + this.setState({recoMessage: resp.description}); + this.setState({loadingInfo: false}); + } + + private clear = () => { + this.setState({recoMessage: null}) + }; + + private clear1() + { + this.setState({recoMessage: null}) + } + + render() { + if (this.state.loadingInfo) + { + return ( Loading your Recommendation ); + } + else + { + if (this.state.recoMessage) + { + return ( + + + Remind me later + Got it + + } + styles={recoStyles} + > + {this.state.recoMessage} + + + ); + } + else + { + return null; + } + + } + + } +} \ No newline at end of file diff --git a/src/Explorer/Recommendations/api.ts b/src/Explorer/Recommendations/api.ts new file mode 100644 index 000000000..b2a1e99df --- /dev/null +++ b/src/Explorer/Recommendations/api.ts @@ -0,0 +1,10 @@ +import { JunoClient } from "../../Juno/JunoClient"; + +export const getRecommendations(endpoint: string): string { + let url = `${endpoint}/api/notebooks/recos`; + const response = await window.fetch(url, { + method: "GET", + headers: JunoClient.getHeaders() + }); + + } \ No newline at end of file diff --git a/src/Juno/JunoClient.ts b/src/Juno/JunoClient.ts index e0fc26884..860793aa8 100644 --- a/src/Juno/JunoClient.ts +++ b/src/Juno/JunoClient.ts @@ -41,6 +41,11 @@ export interface IGalleryItem { pendingScanJobIds: string[]; } +export interface IRecommendationData { + id: number; + description: string; +} + export interface IPublicGalleryData { metadata: IPublicGalleryMetaData; notebooksData: IGalleryItem[]; @@ -127,6 +132,20 @@ export class JunoClient { }; } + public async getRecos(): Promise { + var db = this.databaseAccount().id.split("/"); + var subId = db[2]; + var rg = db[4]; + var acc = db[8]; + const url = `https://localhost/api/recommendations?subId=${subId}&rg=${rg}&account=${acc}`; + const response = await window.fetch(url, { + method: "GET", + headers: JunoClient.getHeaders() + }); + + return response.json(); + } + public async getGitHubToken(code: string): Promise> { const githubParams = JunoClient.getGitHubClientParams(); githubParams.append("code", code); diff --git a/src/explorer.html b/src/explorer.html index 79e6bc738..3e7d6ae35 100644 --- a/src/explorer.html +++ b/src/explorer.html @@ -11,6 +11,11 @@