mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-21 11:47:14 +00:00
recommendations prototype
This commit is contained in:
parent
bd00e5eb9b
commit
3db6276f48
@ -37,6 +37,7 @@ import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer
|
|||||||
import { BrowseQueriesPane } from "./Panes/BrowseQueriesPane";
|
import { BrowseQueriesPane } from "./Panes/BrowseQueriesPane";
|
||||||
import { CassandraAPIDataClient, TableDataClient, TablesAPIDataClient } from "./Tables/TableDataClient";
|
import { CassandraAPIDataClient, TableDataClient, TablesAPIDataClient } from "./Tables/TableDataClient";
|
||||||
import { CommandBarComponentAdapter } from "./Menus/CommandBar/CommandBarComponentAdapter";
|
import { CommandBarComponentAdapter } from "./Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
|
import { RecommendationsAdapter } from "./Recommendations/RecommendationsAdapter";
|
||||||
import { configContext, Platform, updateConfigContext } from "../ConfigContext";
|
import { configContext, Platform, updateConfigContext } from "../ConfigContext";
|
||||||
import { ConsoleData, ConsoleDataType } from "./Menus/NotificationConsole/NotificationConsoleComponent";
|
import { ConsoleData, ConsoleDataType } from "./Menus/NotificationConsole/NotificationConsoleComponent";
|
||||||
import { decryptJWTToken, getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
import { decryptJWTToken, getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||||
@ -207,6 +208,7 @@ export default class Explorer {
|
|||||||
public isLinkInjectionEnabled: ko.Computed<boolean>;
|
public isLinkInjectionEnabled: ko.Computed<boolean>;
|
||||||
public isSettingsV2Enabled: ko.Observable<boolean>;
|
public isSettingsV2Enabled: ko.Observable<boolean>;
|
||||||
public isGitHubPaneEnabled: ko.Observable<boolean>;
|
public isGitHubPaneEnabled: ko.Observable<boolean>;
|
||||||
|
public isRecosEnabled: ko.Observable<boolean>;
|
||||||
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
|
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
|
||||||
public isCopyNotebookPaneEnabled: ko.Observable<boolean>;
|
public isCopyNotebookPaneEnabled: ko.Observable<boolean>;
|
||||||
public isHostedDataExplorerEnabled: ko.Computed<boolean>;
|
public isHostedDataExplorerEnabled: ko.Computed<boolean>;
|
||||||
@ -261,6 +263,7 @@ export default class Explorer {
|
|||||||
private _dialogProps: ko.Observable<DialogProps>;
|
private _dialogProps: ko.Observable<DialogProps>;
|
||||||
private addSynapseLinkDialog: DialogComponentAdapter;
|
private addSynapseLinkDialog: DialogComponentAdapter;
|
||||||
private _addSynapseLinkDialogProps: ko.Observable<DialogProps>;
|
private _addSynapseLinkDialogProps: ko.Observable<DialogProps>;
|
||||||
|
private recommendationsAdapter: RecommendationsAdapter
|
||||||
|
|
||||||
private static readonly MaxNbDatabasesToAutoExpand = 5;
|
private static readonly MaxNbDatabasesToAutoExpand = 5;
|
||||||
|
|
||||||
@ -415,6 +418,7 @@ export default class Explorer {
|
|||||||
//this.isSettingsV2Enabled = ko.computed<boolean>(() => this.isFeatureEnabled(Constants.Features.enableSettingsV2));
|
//this.isSettingsV2Enabled = ko.computed<boolean>(() => this.isFeatureEnabled(Constants.Features.enableSettingsV2));
|
||||||
this.isSettingsV2Enabled = ko.observable(false);
|
this.isSettingsV2Enabled = ko.observable(false);
|
||||||
this.isGitHubPaneEnabled = ko.observable<boolean>(false);
|
this.isGitHubPaneEnabled = ko.observable<boolean>(false);
|
||||||
|
this.isRecosEnabled = ko.observable<boolean>(false);
|
||||||
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||||
this.isCopyNotebookPaneEnabled = ko.observable<boolean>(false);
|
this.isCopyNotebookPaneEnabled = ko.observable<boolean>(false);
|
||||||
|
|
||||||
@ -888,7 +892,7 @@ export default class Explorer {
|
|||||||
|
|
||||||
this.commandBarComponentAdapter = new CommandBarComponentAdapter(this);
|
this.commandBarComponentAdapter = new CommandBarComponentAdapter(this);
|
||||||
this.notificationConsoleComponentAdapter = new NotificationConsoleComponentAdapter(this);
|
this.notificationConsoleComponentAdapter = new NotificationConsoleComponentAdapter(this);
|
||||||
|
|
||||||
this._initSettings();
|
this._initSettings();
|
||||||
|
|
||||||
TelemetryProcessor.traceSuccess(
|
TelemetryProcessor.traceSuccess(
|
||||||
@ -915,6 +919,7 @@ export default class Explorer {
|
|||||||
|
|
||||||
this.gitHubReposPane = this.notebookManager.gitHubReposPane;
|
this.gitHubReposPane = this.notebookManager.gitHubReposPane;
|
||||||
this.isGitHubPaneEnabled(true);
|
this.isGitHubPaneEnabled(true);
|
||||||
|
this.isRecosEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.refreshCommandBarButtons();
|
this.refreshCommandBarButtons();
|
||||||
@ -1001,6 +1006,8 @@ export default class Explorer {
|
|||||||
});
|
});
|
||||||
this.addSynapseLinkDialog = new DialogComponentAdapter();
|
this.addSynapseLinkDialog = new DialogComponentAdapter();
|
||||||
this.addSynapseLinkDialog.parameters = this._addSynapseLinkDialogProps;
|
this.addSynapseLinkDialog.parameters = this._addSynapseLinkDialogProps;
|
||||||
|
this.recommendationsAdapter = new RecommendationsAdapter(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public openEnableSynapseLinkDialog(): void {
|
public openEnableSynapseLinkDialog(): void {
|
||||||
|
50
src/Explorer/Recommendations/RecommendationsAdapter.tsx
Normal file
50
src/Explorer/Recommendations/RecommendationsAdapter.tsx
Normal file
@ -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<number>;
|
||||||
|
public container: Explorer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
constructor(container: Explorer) {
|
||||||
|
this.container = container;
|
||||||
|
this.parameters = ko.observable<number>(Date.now());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public forceRender(): void {
|
||||||
|
window.requestAnimationFrame(() => this.parameters(Date.now()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public renderComponent(): JSX.Element {
|
||||||
|
//const backgroundColor = StyleConstants.BaseLight;
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Recommendations explorer={this.container}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public triggerRender(): void {
|
||||||
|
window.requestAnimationFrame(() => this.parameters(Date.now()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
89
src/Explorer/Recommendations/RecommendationsComponent.tsx
Normal file
89
src/Explorer/Recommendations/RecommendationsComponent.tsx
Normal file
@ -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<IMessageBarStyles> = { 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<RecommendationProps> {
|
||||||
|
|
||||||
|
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 (<React.Fragment> <Spinner/> Loading your Recommendation </React.Fragment>);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this.state.recoMessage)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<MessageBar
|
||||||
|
dismissButtonAriaLabel="Close"
|
||||||
|
messageBarType={MessageBarType.warning}
|
||||||
|
actions={
|
||||||
|
<div>
|
||||||
|
<MessageBarButton onClick={this.clear} styles={recoButtonStyles}>Remind me later</MessageBarButton>
|
||||||
|
<MessageBarButton onClick={this.clear} styles={recoButtonStyles}>Got it</MessageBarButton>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
styles={recoStyles}
|
||||||
|
>
|
||||||
|
{this.state.recoMessage}
|
||||||
|
</MessageBar>
|
||||||
|
|
||||||
|
</React.Fragment>);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
10
src/Explorer/Recommendations/api.ts
Normal file
10
src/Explorer/Recommendations/api.ts
Normal file
@ -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()
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
@ -41,6 +41,11 @@ export interface IGalleryItem {
|
|||||||
pendingScanJobIds: string[];
|
pendingScanJobIds: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IRecommendationData {
|
||||||
|
id: number;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPublicGalleryData {
|
export interface IPublicGalleryData {
|
||||||
metadata: IPublicGalleryMetaData;
|
metadata: IPublicGalleryMetaData;
|
||||||
notebooksData: IGalleryItem[];
|
notebooksData: IGalleryItem[];
|
||||||
@ -127,6 +132,20 @@ export class JunoClient {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getRecos(): Promise<IRecommendationData> {
|
||||||
|
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<IGitHubResponse<IGitHubOAuthToken>> {
|
public async getGitHubToken(code: string): Promise<IGitHubResponse<IGitHubOAuthToken>> {
|
||||||
const githubParams = JunoClient.getGitHubClientParams();
|
const githubParams = JunoClient.getGitHubClientParams();
|
||||||
githubParams.append("code", code);
|
githubParams.append("code", code);
|
||||||
|
@ -11,6 +11,11 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="flexContainer">
|
<div class="flexContainer">
|
||||||
<div id="divExplorer" class="flexContainer hideOverflows" style="display: none">
|
<div id="divExplorer" class="flexContainer hideOverflows" style="display: none">
|
||||||
|
<!-- ko if: isRecosEnabled -->
|
||||||
|
<div>
|
||||||
|
<div data-bind="react: recommendationsAdapter"></div>
|
||||||
|
</div>
|
||||||
|
<!-- /ko -->
|
||||||
<!-- Main Command Bar - Start -->
|
<!-- Main Command Bar - Start -->
|
||||||
<div data-bind="react: commandBarComponentAdapter"></div>
|
<div data-bind="react: commandBarComponentAdapter"></div>
|
||||||
<!-- Main Command Bar - End -->
|
<!-- Main Command Bar - End -->
|
||||||
|
@ -92,7 +92,7 @@ module.exports = function(env = {}, argv = {}) {
|
|||||||
const rules = [fontRule, lessRule, imagesRule, cssRule, htmlRule, typescriptRule];
|
const rules = [fontRule, lessRule, imagesRule, cssRule, htmlRule, typescriptRule];
|
||||||
const envVars = {
|
const envVars = {
|
||||||
GIT_SHA: gitSha,
|
GIT_SHA: gitSha,
|
||||||
PORT: process.env.PORT || "1234"
|
PORT: process.env.PORT || "2223"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mode === "production") {
|
if (mode === "production") {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user