mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 09:20:16 +00:00
Prettier 2.0 (#393)
This commit is contained in:
@@ -1,292 +1,292 @@
|
||||
import * as _ from "underscore";
|
||||
import * as React from "react";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import * as DataModels from "../../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import {
|
||||
DetailsList,
|
||||
DetailsListLayoutMode,
|
||||
IDetailsListProps,
|
||||
IDetailsRowProps,
|
||||
DetailsRow
|
||||
} from "office-ui-fabric-react/lib/DetailsList";
|
||||
import { FocusZone } from "office-ui-fabric-react/lib/FocusZone";
|
||||
import { IconButton, IButtonProps } from "office-ui-fabric-react/lib/Button";
|
||||
import { IColumn } from "office-ui-fabric-react/lib/DetailsList";
|
||||
import { IContextualMenuProps, ContextualMenu } from "office-ui-fabric-react/lib/ContextualMenu";
|
||||
import {
|
||||
IObjectWithKey,
|
||||
ISelectionZoneProps,
|
||||
Selection,
|
||||
SelectionMode,
|
||||
SelectionZone
|
||||
} from "office-ui-fabric-react/lib/utilities/selection/index";
|
||||
import { StyleConstants } from "../../../Common/Constants";
|
||||
import { TextField, ITextFieldProps, ITextField } from "office-ui-fabric-react/lib/TextField";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
|
||||
import SaveQueryBannerIcon from "../../../../images/save_query_banner.png";
|
||||
import { QueriesClient } from "../../../Common/QueriesClient";
|
||||
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
||||
|
||||
export interface QueriesGridComponentProps {
|
||||
queriesClient: QueriesClient;
|
||||
onQuerySelect: (query: DataModels.Query) => void;
|
||||
containerVisible: boolean;
|
||||
saveQueryEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface QueriesGridComponentState {
|
||||
queries: Query[];
|
||||
filteredResults: Query[];
|
||||
}
|
||||
|
||||
interface Query extends DataModels.Query, IObjectWithKey {
|
||||
key: string;
|
||||
}
|
||||
|
||||
export class QueriesGridComponent extends React.Component<QueriesGridComponentProps, QueriesGridComponentState> {
|
||||
private selection: Selection;
|
||||
private queryFilter: ITextField;
|
||||
|
||||
constructor(props: QueriesGridComponentProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
queries: [],
|
||||
filteredResults: []
|
||||
};
|
||||
this.selection = new Selection();
|
||||
this.selection.setItems(this.state.filteredResults);
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: QueriesGridComponentProps, prevState: QueriesGridComponentState): void {
|
||||
this.selection.setItems(
|
||||
this.state.filteredResults,
|
||||
!_.isEqual(prevState.filteredResults, this.state.filteredResults)
|
||||
);
|
||||
this.queryFilter && this.queryFilter.focus();
|
||||
const querySetupCompleted: boolean = !prevProps.saveQueryEnabled && this.props.saveQueryEnabled;
|
||||
const noQueryFiltersApplied: boolean = !this.queryFilter || !this.queryFilter.value;
|
||||
if (!this.props.containerVisible || !this.props.saveQueryEnabled) {
|
||||
return;
|
||||
} else if (noQueryFiltersApplied && (!prevProps.containerVisible || querySetupCompleted)) {
|
||||
// refresh only when pane is opened or query setup was recently completed
|
||||
this.fetchSavedQueries();
|
||||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
if (this.state.queries.length === 0) {
|
||||
return this.renderBannerComponent();
|
||||
}
|
||||
return this.renderQueryGridComponent();
|
||||
}
|
||||
|
||||
private renderQueryGridComponent(): JSX.Element {
|
||||
const searchFilterProps: ITextFieldProps = {
|
||||
placeholder: "Search for Queries",
|
||||
ariaLabel: "Query filter input",
|
||||
onChange: this.onFilterInputChange,
|
||||
componentRef: (queryInput: ITextField) => (this.queryFilter = queryInput),
|
||||
styles: {
|
||||
root: { paddingBottom: "12px" },
|
||||
field: { fontSize: `${StyleConstants.mediumFontSize}px` }
|
||||
}
|
||||
};
|
||||
const selectionContainerProps: ISelectionZoneProps = {
|
||||
selection: this.selection,
|
||||
selectionMode: SelectionMode.single,
|
||||
onItemInvoked: (item: Query) => this.props.onQuerySelect(item)
|
||||
};
|
||||
const detailsListProps: IDetailsListProps = {
|
||||
items: this.state.filteredResults,
|
||||
columns: this.getColumns(),
|
||||
isHeaderVisible: false,
|
||||
setKey: "queryName",
|
||||
layoutMode: DetailsListLayoutMode.fixedColumns,
|
||||
selection: this.selection,
|
||||
selectionMode: SelectionMode.none,
|
||||
compact: true,
|
||||
onRenderRow: this.onRenderRow,
|
||||
styles: {
|
||||
root: { width: "100%" }
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FocusZone style={{ width: "100%" }}>
|
||||
<TextField {...searchFilterProps} />
|
||||
<SelectionZone {...selectionContainerProps}>
|
||||
<DetailsList {...detailsListProps} />
|
||||
</SelectionZone>
|
||||
</FocusZone>
|
||||
);
|
||||
}
|
||||
|
||||
private renderBannerComponent(): JSX.Element {
|
||||
const bannerProps: React.ImgHTMLAttributes<HTMLImageElement> = {
|
||||
src: SaveQueryBannerIcon,
|
||||
alt: "Save query helper banner",
|
||||
style: {
|
||||
height: "150px",
|
||||
width: "310px",
|
||||
marginTop: "20px",
|
||||
border: `1px solid ${StyleConstants.BaseMedium}`
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
You have not saved any queries yet. <br /> <br />
|
||||
To write a new query, open a new query tab and enter the desired query. Once ready to save, click on Save
|
||||
Query and follow the prompt in order to save the query.
|
||||
</div>
|
||||
<img {...bannerProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private onFilterInputChange = (event: React.FormEvent<HTMLInputElement>, query: string): void => {
|
||||
if (query) {
|
||||
const filteredQueries: Query[] = this.state.queries.filter(
|
||||
(savedQuery: Query) =>
|
||||
savedQuery.queryName.indexOf(query) > -1 || savedQuery.queryName.toLowerCase().indexOf(query) > -1
|
||||
);
|
||||
this.setState({
|
||||
filteredResults: filteredQueries
|
||||
});
|
||||
} else {
|
||||
// no filter
|
||||
this.setState({
|
||||
filteredResults: this.state.queries
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private onRenderRow = (props: IDetailsRowProps): JSX.Element => {
|
||||
props.styles = {
|
||||
root: { width: "100%" },
|
||||
fields: {
|
||||
width: "100%",
|
||||
justifyContent: "space-between"
|
||||
},
|
||||
cell: {
|
||||
margin: "auto 0"
|
||||
}
|
||||
};
|
||||
return <DetailsRow data-selection-invoke={true} {...props} />;
|
||||
};
|
||||
|
||||
private getColumns(): IColumn[] {
|
||||
return [
|
||||
{
|
||||
key: "Name",
|
||||
name: "Name",
|
||||
fieldName: "queryName",
|
||||
minWidth: 260
|
||||
},
|
||||
{
|
||||
key: "Action",
|
||||
name: "Action",
|
||||
fieldName: null,
|
||||
minWidth: 70,
|
||||
onRender: (query: Query, index: number, column: IColumn) => {
|
||||
const buttonProps: IButtonProps = {
|
||||
iconProps: {
|
||||
iconName: "More",
|
||||
title: "More",
|
||||
ariaLabel: "More actions button"
|
||||
},
|
||||
menuIconProps: {
|
||||
styles: { root: { display: "none" } }
|
||||
},
|
||||
menuProps: {
|
||||
isBeakVisible: true,
|
||||
items: [
|
||||
{
|
||||
key: "Open",
|
||||
text: "Open query",
|
||||
onClick: (event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, menuItem: any) => {
|
||||
this.props.onQuerySelect(query);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "Delete",
|
||||
text: "Delete query",
|
||||
onClick: async (
|
||||
event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,
|
||||
menuItem: any
|
||||
) => {
|
||||
if (window.confirm("Are you sure you want to delete this query?")) {
|
||||
const container = window.dataExplorer;
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteSavedQuery, {
|
||||
databaseAccountName: container && container.databaseAccount().name,
|
||||
defaultExperience: container && container.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: container && container.browseQueriesPane.title()
|
||||
});
|
||||
try {
|
||||
await this.props.queriesClient.deleteQuery(query);
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.DeleteSavedQuery,
|
||||
{
|
||||
databaseAccountName: container && container.databaseAccount().name,
|
||||
defaultExperience: container && container.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: container && container.browseQueriesPane.title()
|
||||
},
|
||||
startKey
|
||||
);
|
||||
} catch (error) {
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.DeleteSavedQuery,
|
||||
{
|
||||
databaseAccountName: container && container.databaseAccount().name,
|
||||
defaultExperience: container && container.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: container && container.browseQueriesPane.title(),
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error)
|
||||
},
|
||||
startKey
|
||||
);
|
||||
}
|
||||
await this.fetchSavedQueries(); // get latest state
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
menuAs: (menuProps: IContextualMenuProps): JSX.Element => {
|
||||
return <ContextualMenu {...menuProps} />;
|
||||
}
|
||||
};
|
||||
return <IconButton {...buttonProps} />;
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private async fetchSavedQueries(): Promise<void> {
|
||||
let queries: Query[];
|
||||
try {
|
||||
queries = (await this.props.queriesClient.getQueries()) as Query[];
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
queries = queries.map((query: Query) => {
|
||||
query.key = query.queryName;
|
||||
return query;
|
||||
});
|
||||
|
||||
// we do a deep equality check before setting the state to avoid infinite re-renders
|
||||
if (!_.isEqual(queries, this.state.queries)) {
|
||||
this.setState({
|
||||
filteredResults: queries,
|
||||
queries: queries
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
import * as _ from "underscore";
|
||||
import * as React from "react";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import * as DataModels from "../../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import {
|
||||
DetailsList,
|
||||
DetailsListLayoutMode,
|
||||
IDetailsListProps,
|
||||
IDetailsRowProps,
|
||||
DetailsRow,
|
||||
} from "office-ui-fabric-react/lib/DetailsList";
|
||||
import { FocusZone } from "office-ui-fabric-react/lib/FocusZone";
|
||||
import { IconButton, IButtonProps } from "office-ui-fabric-react/lib/Button";
|
||||
import { IColumn } from "office-ui-fabric-react/lib/DetailsList";
|
||||
import { IContextualMenuProps, ContextualMenu } from "office-ui-fabric-react/lib/ContextualMenu";
|
||||
import {
|
||||
IObjectWithKey,
|
||||
ISelectionZoneProps,
|
||||
Selection,
|
||||
SelectionMode,
|
||||
SelectionZone,
|
||||
} from "office-ui-fabric-react/lib/utilities/selection/index";
|
||||
import { StyleConstants } from "../../../Common/Constants";
|
||||
import { TextField, ITextFieldProps, ITextField } from "office-ui-fabric-react/lib/TextField";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
|
||||
import SaveQueryBannerIcon from "../../../../images/save_query_banner.png";
|
||||
import { QueriesClient } from "../../../Common/QueriesClient";
|
||||
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
||||
|
||||
export interface QueriesGridComponentProps {
|
||||
queriesClient: QueriesClient;
|
||||
onQuerySelect: (query: DataModels.Query) => void;
|
||||
containerVisible: boolean;
|
||||
saveQueryEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface QueriesGridComponentState {
|
||||
queries: Query[];
|
||||
filteredResults: Query[];
|
||||
}
|
||||
|
||||
interface Query extends DataModels.Query, IObjectWithKey {
|
||||
key: string;
|
||||
}
|
||||
|
||||
export class QueriesGridComponent extends React.Component<QueriesGridComponentProps, QueriesGridComponentState> {
|
||||
private selection: Selection;
|
||||
private queryFilter: ITextField;
|
||||
|
||||
constructor(props: QueriesGridComponentProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
queries: [],
|
||||
filteredResults: [],
|
||||
};
|
||||
this.selection = new Selection();
|
||||
this.selection.setItems(this.state.filteredResults);
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: QueriesGridComponentProps, prevState: QueriesGridComponentState): void {
|
||||
this.selection.setItems(
|
||||
this.state.filteredResults,
|
||||
!_.isEqual(prevState.filteredResults, this.state.filteredResults)
|
||||
);
|
||||
this.queryFilter && this.queryFilter.focus();
|
||||
const querySetupCompleted: boolean = !prevProps.saveQueryEnabled && this.props.saveQueryEnabled;
|
||||
const noQueryFiltersApplied: boolean = !this.queryFilter || !this.queryFilter.value;
|
||||
if (!this.props.containerVisible || !this.props.saveQueryEnabled) {
|
||||
return;
|
||||
} else if (noQueryFiltersApplied && (!prevProps.containerVisible || querySetupCompleted)) {
|
||||
// refresh only when pane is opened or query setup was recently completed
|
||||
this.fetchSavedQueries();
|
||||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
if (this.state.queries.length === 0) {
|
||||
return this.renderBannerComponent();
|
||||
}
|
||||
return this.renderQueryGridComponent();
|
||||
}
|
||||
|
||||
private renderQueryGridComponent(): JSX.Element {
|
||||
const searchFilterProps: ITextFieldProps = {
|
||||
placeholder: "Search for Queries",
|
||||
ariaLabel: "Query filter input",
|
||||
onChange: this.onFilterInputChange,
|
||||
componentRef: (queryInput: ITextField) => (this.queryFilter = queryInput),
|
||||
styles: {
|
||||
root: { paddingBottom: "12px" },
|
||||
field: { fontSize: `${StyleConstants.mediumFontSize}px` },
|
||||
},
|
||||
};
|
||||
const selectionContainerProps: ISelectionZoneProps = {
|
||||
selection: this.selection,
|
||||
selectionMode: SelectionMode.single,
|
||||
onItemInvoked: (item: Query) => this.props.onQuerySelect(item),
|
||||
};
|
||||
const detailsListProps: IDetailsListProps = {
|
||||
items: this.state.filteredResults,
|
||||
columns: this.getColumns(),
|
||||
isHeaderVisible: false,
|
||||
setKey: "queryName",
|
||||
layoutMode: DetailsListLayoutMode.fixedColumns,
|
||||
selection: this.selection,
|
||||
selectionMode: SelectionMode.none,
|
||||
compact: true,
|
||||
onRenderRow: this.onRenderRow,
|
||||
styles: {
|
||||
root: { width: "100%" },
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<FocusZone style={{ width: "100%" }}>
|
||||
<TextField {...searchFilterProps} />
|
||||
<SelectionZone {...selectionContainerProps}>
|
||||
<DetailsList {...detailsListProps} />
|
||||
</SelectionZone>
|
||||
</FocusZone>
|
||||
);
|
||||
}
|
||||
|
||||
private renderBannerComponent(): JSX.Element {
|
||||
const bannerProps: React.ImgHTMLAttributes<HTMLImageElement> = {
|
||||
src: SaveQueryBannerIcon,
|
||||
alt: "Save query helper banner",
|
||||
style: {
|
||||
height: "150px",
|
||||
width: "310px",
|
||||
marginTop: "20px",
|
||||
border: `1px solid ${StyleConstants.BaseMedium}`,
|
||||
},
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
You have not saved any queries yet. <br /> <br />
|
||||
To write a new query, open a new query tab and enter the desired query. Once ready to save, click on Save
|
||||
Query and follow the prompt in order to save the query.
|
||||
</div>
|
||||
<img {...bannerProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private onFilterInputChange = (event: React.FormEvent<HTMLInputElement>, query: string): void => {
|
||||
if (query) {
|
||||
const filteredQueries: Query[] = this.state.queries.filter(
|
||||
(savedQuery: Query) =>
|
||||
savedQuery.queryName.indexOf(query) > -1 || savedQuery.queryName.toLowerCase().indexOf(query) > -1
|
||||
);
|
||||
this.setState({
|
||||
filteredResults: filteredQueries,
|
||||
});
|
||||
} else {
|
||||
// no filter
|
||||
this.setState({
|
||||
filteredResults: this.state.queries,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private onRenderRow = (props: IDetailsRowProps): JSX.Element => {
|
||||
props.styles = {
|
||||
root: { width: "100%" },
|
||||
fields: {
|
||||
width: "100%",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
cell: {
|
||||
margin: "auto 0",
|
||||
},
|
||||
};
|
||||
return <DetailsRow data-selection-invoke={true} {...props} />;
|
||||
};
|
||||
|
||||
private getColumns(): IColumn[] {
|
||||
return [
|
||||
{
|
||||
key: "Name",
|
||||
name: "Name",
|
||||
fieldName: "queryName",
|
||||
minWidth: 260,
|
||||
},
|
||||
{
|
||||
key: "Action",
|
||||
name: "Action",
|
||||
fieldName: null,
|
||||
minWidth: 70,
|
||||
onRender: (query: Query, index: number, column: IColumn) => {
|
||||
const buttonProps: IButtonProps = {
|
||||
iconProps: {
|
||||
iconName: "More",
|
||||
title: "More",
|
||||
ariaLabel: "More actions button",
|
||||
},
|
||||
menuIconProps: {
|
||||
styles: { root: { display: "none" } },
|
||||
},
|
||||
menuProps: {
|
||||
isBeakVisible: true,
|
||||
items: [
|
||||
{
|
||||
key: "Open",
|
||||
text: "Open query",
|
||||
onClick: (event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, menuItem: any) => {
|
||||
this.props.onQuerySelect(query);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Delete",
|
||||
text: "Delete query",
|
||||
onClick: async (
|
||||
event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,
|
||||
menuItem: any
|
||||
) => {
|
||||
if (window.confirm("Are you sure you want to delete this query?")) {
|
||||
const container = window.dataExplorer;
|
||||
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteSavedQuery, {
|
||||
databaseAccountName: container && container.databaseAccount().name,
|
||||
defaultExperience: container && container.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: container && container.browseQueriesPane.title(),
|
||||
});
|
||||
try {
|
||||
await this.props.queriesClient.deleteQuery(query);
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.DeleteSavedQuery,
|
||||
{
|
||||
databaseAccountName: container && container.databaseAccount().name,
|
||||
defaultExperience: container && container.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: container && container.browseQueriesPane.title(),
|
||||
},
|
||||
startKey
|
||||
);
|
||||
} catch (error) {
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.DeleteSavedQuery,
|
||||
{
|
||||
databaseAccountName: container && container.databaseAccount().name,
|
||||
defaultExperience: container && container.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: container && container.browseQueriesPane.title(),
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
);
|
||||
}
|
||||
await this.fetchSavedQueries(); // get latest state
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
menuAs: (menuProps: IContextualMenuProps): JSX.Element => {
|
||||
return <ContextualMenu {...menuProps} />;
|
||||
},
|
||||
};
|
||||
return <IconButton {...buttonProps} />;
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
private async fetchSavedQueries(): Promise<void> {
|
||||
let queries: Query[];
|
||||
try {
|
||||
queries = (await this.props.queriesClient.getQueries()) as Query[];
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
queries = queries.map((query: Query) => {
|
||||
query.key = query.queryName;
|
||||
return query;
|
||||
});
|
||||
|
||||
// we do a deep equality check before setting the state to avoid infinite re-renders
|
||||
if (!_.isEqual(queries, this.state.queries)) {
|
||||
this.setState({
|
||||
filteredResults: queries,
|
||||
queries: queries,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/**
|
||||
* This adapter is responsible to render the QueriesGrid 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 * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { QueriesGridComponent, QueriesGridComponentProps } from "./QueriesGridComponent";
|
||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||
import Explorer from "../../Explorer";
|
||||
|
||||
export class QueriesGridComponentAdapter implements ReactAdapter {
|
||||
public parameters: ko.Observable<number>;
|
||||
|
||||
constructor(private container: Explorer) {
|
||||
this.parameters = ko.observable<number>(Date.now());
|
||||
}
|
||||
|
||||
public renderComponent(): JSX.Element {
|
||||
const props: QueriesGridComponentProps = {
|
||||
queriesClient: this.container.queriesClient,
|
||||
onQuerySelect: this.container.browseQueriesPane.loadSavedQuery,
|
||||
containerVisible: this.container.browseQueriesPane.visible(),
|
||||
saveQueryEnabled: this.container.canSaveQueries()
|
||||
};
|
||||
return <QueriesGridComponent {...props} />;
|
||||
}
|
||||
|
||||
public forceRender(): void {
|
||||
window.requestAnimationFrame(() => this.parameters(Date.now()));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This adapter is responsible to render the QueriesGrid 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 * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { QueriesGridComponent, QueriesGridComponentProps } from "./QueriesGridComponent";
|
||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||
import Explorer from "../../Explorer";
|
||||
|
||||
export class QueriesGridComponentAdapter implements ReactAdapter {
|
||||
public parameters: ko.Observable<number>;
|
||||
|
||||
constructor(private container: Explorer) {
|
||||
this.parameters = ko.observable<number>(Date.now());
|
||||
}
|
||||
|
||||
public renderComponent(): JSX.Element {
|
||||
const props: QueriesGridComponentProps = {
|
||||
queriesClient: this.container.queriesClient,
|
||||
onQuerySelect: this.container.browseQueriesPane.loadSavedQuery,
|
||||
containerVisible: this.container.browseQueriesPane.visible(),
|
||||
saveQueryEnabled: this.container.canSaveQueries(),
|
||||
};
|
||||
return <QueriesGridComponent {...props} />;
|
||||
}
|
||||
|
||||
public forceRender(): void {
|
||||
window.requestAnimationFrame(() => this.parameters(Date.now()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user