mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Initial changes for reusable QDS report (#23527)
* initial changes for making a QDS report with placeholders * Add icon for configure button * Add another example report to show layout * move files * add placeholder names to components and cleanup toolbar * cleanup * switch to createViews() instead of createTop and BottomSections() * add QueryStoreView class for the different components in a report * cleanup * add more comments * fix yarn not running for query store extension folder * add missing break * change one more view to container
This commit is contained in:
3
extensions/query-store/images/dark/gear.svg
Normal file
3
extensions/query-store/images/dark/gear.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.09976 4.4L8.59976 2H7.39976L6.89976 4.4L6.19976 4.7L4.19976 3.4L3.29976 4.2L4.59976 6.2L4.39976 6.9L1.99976 7.4V8.6L4.39976 9.1L4.69976 9.9L3.39976 11.9L4.19976 12.7L6.19976 11.4L6.99976 11.7L7.39976 14H8.59976L9.09976 11.6L9.89976 11.3L11.8998 12.6L12.6998 11.8L11.3998 9.8L11.6998 9L13.9998 8.6V7.4L11.5998 6.9L11.2998 6.1L12.5998 4.1L11.7998 3.3L9.79976 4.6L9.09976 4.4ZM9.39976 1L9.89976 3.4L11.9998 2.1L13.9998 4.1L12.5998 6.2L14.9998 6.6V9.4L12.5998 9.9L13.9998 12L11.9998 14L9.89976 12.6L9.39976 15H6.59976L6.09976 12.6L3.99976 13.9L1.99976 11.9L3.39976 9.8L0.999756 9.4V6.6L3.39976 6.1L2.09976 4L4.09976 2L6.19976 3.4L6.59976 1H9.39976ZM9.99976 8C9.99976 9.1 9.09976 10 7.99976 10C6.89976 10 5.99976 9.1 5.99976 8C5.99976 6.9 6.89976 6 7.99976 6C9.09976 6 9.99976 6.9 9.99976 8ZM7.99976 9C8.59976 9 8.99976 8.6 8.99976 8C8.99976 7.4 8.59976 7 7.99976 7C7.39976 7 6.99976 7.4 6.99976 8C6.99976 8.6 7.39976 9 7.99976 9Z" fill="#C5C5C5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
3
extensions/query-store/images/light/gear.svg
Normal file
3
extensions/query-store/images/light/gear.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.1 4.4L8.6 2H7.4L6.9 4.4L6.2 4.7L4.2 3.4L3.3 4.2L4.6 6.2L4.4 6.9L2 7.4V8.6L4.4 9.1L4.7 9.9L3.4 11.9L4.2 12.7L6.2 11.4L7 11.7L7.4 14H8.6L9.1 11.6L9.9 11.3L11.9 12.6L12.7 11.8L11.4 9.8L11.7 9L14 8.6V7.4L11.6 6.9L11.3 6.1L12.6 4.1L11.8 3.3L9.8 4.6L9.1 4.4ZM9.4 1L9.9 3.4L12 2.1L14 4.1L12.6 6.2L15 6.6V9.4L12.6 9.9L14 12L12 14L9.9 12.6L9.4 15H6.6L6.1 12.6L4 13.9L2 11.9L3.4 9.8L1 9.4V6.6L3.4 6.1L2.1 4L4.1 2L6.2 3.4L6.6 1H9.4ZM10 8C10 9.1 9.1 10 8 10C6.9 10 6 9.1 6 8C6 6.9 6.9 6 8 6C9.1 6 10 6.9 10 8ZM8 9C8.6 9 9 8.6 9 8C9 7.4 8.6 7 8 7C7.4 7 7 7.4 7 8C7 8.6 7.4 9 8 9Z" fill="#424242"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 700 B |
@@ -13,7 +13,8 @@
|
||||
"icon": "images/extension.png",
|
||||
"aiKey": "29a207bb14f84905966a8f22524cb730-25407f35-11b6-4d4e-8114-ab9e843cb52f-7380",
|
||||
"activationEvents": [
|
||||
"*"
|
||||
"onCommand:queryStore.topResourceConsumingQueriesOpen",
|
||||
"onCommand:queryStore.overallResourceConsumptionOpen"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"repository": {
|
||||
@@ -31,6 +32,16 @@
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "queryStore.topResourceConsumingQueriesOpen",
|
||||
"title": "%queryStore.topResourceConsumingQueriesOpen%",
|
||||
"category": "%queryStore.category%"
|
||||
},
|
||||
{
|
||||
"command": "queryStore.overallResourceConsumptionOpen",
|
||||
"title": "%queryStore.overallResourceConsumptionOpen%",
|
||||
"category": "%queryStore.category%"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"objectExplorer/item/context": [
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"queryStore.displayName": "Query Store",
|
||||
"queryStore.description": "Query Store extension for Azure Data Studio."
|
||||
"queryStore.description": "Query Store extension for Azure Data Studio.",
|
||||
"queryStore.category": "Query Store",
|
||||
"queryStore.topResourceConsumingQueriesOpen": "Open Top Resource Consuming Queries",
|
||||
"queryStore.overallResourceConsumptionOpen": "Open Overall Resource Consumption"
|
||||
}
|
||||
|
||||
23
extensions/query-store/src/common/constants.ts
Normal file
23
extensions/query-store/src/common/constants.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export const overallResourceConsumption = localize('overallResourceConsumption', "Overall Resource Consumption");
|
||||
export const duration = localize('duration', "Duration");
|
||||
export const executionCount = localize('executionCount', "Execution Count");
|
||||
export const cpuTime = localize('cpuTime', "CPU Time");
|
||||
export const logicalReads = localize('logicalReads', "Logical Reads");
|
||||
export function overallResourceConsumptionToolbarLabel(databaseName: string): string { return localize('overallResourceConsumptionToolbarLabel', "Overall resource consumption for database {0}", databaseName); }
|
||||
|
||||
export const topResourceConsumingQueries = localize('topResourceConsumingQueries', "Top Resource Consuming Queries");
|
||||
export const queries = localize('queries', "Queries");
|
||||
export function planSummary(queryId: string): string { return localize('planSummary', "Plan Summary for query {0}", queryId); }
|
||||
export function plan(queryId: string): string { return localize('plan', "Plan {0}", queryId); }
|
||||
export function topResourceConsumingQueriesToolbarLabel(databaseName: string): string { return localize('topResourceConsumingQueriesToolbarLabel', "Top 25 resource consumers for database {0}", databaseName); }
|
||||
|
||||
export const configure = localize('configure', "Configure");
|
||||
78
extensions/query-store/src/common/utils.ts
Normal file
78
extensions/query-store/src/common/utils.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
/**
|
||||
* Creates a flex container with the provided component and sets the background color
|
||||
* TODO: Remove/redo this helper function after chart components are hooked up, when background color is no longer used
|
||||
* @param view
|
||||
* @param component
|
||||
* @param backgroundColor
|
||||
* @returns Flex container with the specified background color containing component
|
||||
*/
|
||||
export async function createOneComponentFlexContainer(view: azdata.ModelView, component: azdata.Component, backgroundColor: string): Promise<azdata.FlexContainer> {
|
||||
const flexContainer = view.modelBuilder.flexContainer().component();
|
||||
|
||||
await flexContainer.updateCssStyles({ 'background-color': backgroundColor });
|
||||
|
||||
flexContainer.addItem(component);
|
||||
|
||||
flexContainer.setLayout({
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
});
|
||||
|
||||
return flexContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a flex container with two components, either horizontally or vertically based on the passed in flexFlow
|
||||
* @param view
|
||||
* @param firstComponent
|
||||
* @param secondComponent
|
||||
* @param flexFlow row or column
|
||||
* @returns Flex container containing the two components
|
||||
*/
|
||||
export async function createTwoComponentFlexContainer(view: azdata.ModelView, firstComponent: azdata.Component, secondComponent: azdata.Component, flexFlow: string): Promise<azdata.FlexContainer> {
|
||||
const flexContainer = view.modelBuilder.flexContainer().component();
|
||||
|
||||
if (flexFlow === 'row') {
|
||||
flexContainer.addItems([firstComponent, secondComponent], { CSSStyles: { 'width': '50%' } });
|
||||
} else {
|
||||
flexContainer.addItems([firstComponent, secondComponent], { CSSStyles: { 'height': '50%' } });
|
||||
}
|
||||
|
||||
flexContainer.setLayout({
|
||||
flexFlow: flexFlow,
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
});
|
||||
|
||||
return flexContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a vertical splitview
|
||||
* @param view
|
||||
* @param topComponent
|
||||
* @param bottomComponent
|
||||
* @param splitViewHeight
|
||||
* @returns Vertical SplitViewContainer with the top and bottom components
|
||||
*/
|
||||
export function createVerticalSplitView(view: azdata.ModelView, topComponent: azdata.Component, bottomComponent: azdata.Component, splitViewHeight: number): azdata.SplitViewContainer {
|
||||
// TODO: figure out why the horizontal spliview isn't working
|
||||
|
||||
const splitview = <azdata.SplitViewContainer>view.modelBuilder.splitViewContainer().component();
|
||||
splitview.addItem(topComponent);
|
||||
splitview.addItem(bottomComponent);
|
||||
|
||||
splitview.setLayout({
|
||||
orientation: 'vertical',
|
||||
splitViewHeight: splitViewHeight
|
||||
});
|
||||
|
||||
return splitview;
|
||||
}
|
||||
@@ -4,8 +4,13 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { TopResourceConsumingQueries } from './reports/topResourceConsumingQueries';
|
||||
import { OverallResourceConsumption } from './reports/overallResourceConsumption';
|
||||
|
||||
export async function activate(_context: vscode.ExtensionContext): Promise<void> {
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<void> {
|
||||
// TODO: get db name
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryStore.topResourceConsumingQueriesOpen', async () => { await new TopResourceConsumingQueries(context, 'WideWorldImporters').open() }));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryStore.overallResourceConsumptionOpen', async () => { await new OverallResourceConsumption(context, 'WideWorldImporters').open() }));
|
||||
}
|
||||
|
||||
export function deactivate(): void {
|
||||
|
||||
146
extensions/query-store/src/reports/baseQueryStoreReport.ts
Normal file
146
extensions/query-store/src/reports/baseQueryStoreReport.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as path from 'path';
|
||||
import * as utils from '../common/utils';
|
||||
import * as constants from '../common/constants';
|
||||
|
||||
export abstract class BaseQueryStoreReport {
|
||||
protected editor: azdata.workspace.ModelViewEditor;
|
||||
protected flexModel?: azdata.FlexContainer;
|
||||
|
||||
constructor(reportName: string, private reportTitle: string, protected resizeable: boolean, private extensionContext: vscode.ExtensionContext) {
|
||||
this.editor = azdata.workspace.createModelViewEditor(reportName, { retainContextWhenHidden: true, supportsSave: false }, reportName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and opens the report
|
||||
*/
|
||||
public async open(): Promise<void> {
|
||||
this.editor.registerContent(async (view) => {
|
||||
this.flexModel = <azdata.FlexContainer>view.modelBuilder.flexContainer().component();
|
||||
|
||||
const toolbar = await this.createToolbar(view);
|
||||
this.flexModel.addItem(toolbar, { flex: 'none' });
|
||||
|
||||
const views = await this.createViews(view);
|
||||
|
||||
const mainContainer = await this.createMainContainer(view, views);
|
||||
|
||||
this.flexModel.addItem(mainContainer, { CSSStyles: { 'width': '100%', 'height': '100%' } });
|
||||
|
||||
this.flexModel.setLayout({
|
||||
flexFlow: 'column',
|
||||
height: '100%'
|
||||
});
|
||||
|
||||
await view.initializeModel(this.flexModel);
|
||||
});
|
||||
|
||||
await this.editor.openEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main container containing the different components of the report
|
||||
* @param view
|
||||
* @param containers Array of containers to add to the main container
|
||||
* @returns FlexContainer or SplitViewContainer containing the containers
|
||||
*/
|
||||
private async createMainContainer(view: azdata.ModelView, containers: azdata.FlexContainer[]): Promise<azdata.FlexContainer | azdata.SplitViewContainer> {
|
||||
let mainContainer;
|
||||
|
||||
switch (containers.length) {
|
||||
case 1: {
|
||||
mainContainer = containers[0];
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// TODO: replace 800 to have the number be based on how big the window is
|
||||
// one container on top, one on the bottom
|
||||
mainContainer = this.resizeable ? utils.createVerticalSplitView(view, containers[0], containers[1], 800) : await utils.createTwoComponentFlexContainer(view, containers[0], containers[1], 'column');
|
||||
break;
|
||||
} case 3: {
|
||||
// 2 containers on top, one on the bottom
|
||||
// TODO: support portrait and landscape view. Right now it's landscape view only
|
||||
mainContainer = this.resizeable ? utils.createVerticalSplitView(view, await utils.createTwoComponentFlexContainer(view, containers[0], containers[1], 'row'), containers[2], 800)
|
||||
: await utils.createTwoComponentFlexContainer(view, await utils.createTwoComponentFlexContainer(view, containers[0], containers[1], 'row'), containers[2], 'column');
|
||||
break;
|
||||
} case 4: {
|
||||
// 2 containers on top, 2 on the bottom
|
||||
mainContainer = this.resizeable ? utils.createVerticalSplitView(view, await utils.createTwoComponentFlexContainer(view, containers[0], containers[1], 'row'), await utils.createTwoComponentFlexContainer(view, containers[2], containers[3], 'row'), 800)
|
||||
: await utils.createTwoComponentFlexContainer(view, await utils.createTwoComponentFlexContainer(view, containers[0], containers[1], 'row'), await utils.createTwoComponentFlexContainer(view, containers[2], containers[3], 'row'), 'column');
|
||||
break;
|
||||
} default: {
|
||||
throw new Error(`{views.length} number of views in a QDS report is not supported`);
|
||||
}
|
||||
}
|
||||
|
||||
return mainContainer
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the toolbar for the overall report with the report title, time range, and configure button
|
||||
* @param view
|
||||
*/
|
||||
protected async createToolbar(view: azdata.ModelView): Promise<azdata.ToolbarContainer> {
|
||||
const toolBar = <azdata.ToolbarBuilder>view.modelBuilder.toolbarContainer().withProps({
|
||||
CSSStyles: { 'padding': '5px' }
|
||||
});
|
||||
|
||||
const reportTitle = view.modelBuilder.text().withProps({
|
||||
value: this.reportTitle,
|
||||
title: this.reportTitle,
|
||||
CSSStyles: { 'margin-top': '5px', 'margin-bottom': '5px', 'margin-right': '15px' }
|
||||
}).component();
|
||||
|
||||
// TODO: get time from configuration dialog
|
||||
const timePeriod = view.modelBuilder.text().withProps({
|
||||
// placeholder times
|
||||
value: 'Time period: 5/15/2023 11:58 AM - 5/23/2023 11:58 AM',
|
||||
title: 'Time period: 5/15/2023 11:58 AM - 5/23/2023 11:58 AM',
|
||||
CSSStyles: { 'margin-top': '5px', 'margin-bottom': '5px', 'margin-right': '15px' }
|
||||
}).component();
|
||||
|
||||
const configureButton = view.modelBuilder.button().withProps({
|
||||
label: constants.configure,
|
||||
title: constants.configure,
|
||||
iconPath: {
|
||||
light: path.join(this.extensionContext.extensionPath, 'images', 'light', 'gear.svg'),
|
||||
dark: path.join(this.extensionContext.extensionPath, 'images', 'dark', 'gear.svg')
|
||||
}
|
||||
}).component();
|
||||
|
||||
// TODO: enable after the configuration dialog is implemented
|
||||
configureButton.enabled = false;
|
||||
|
||||
configureButton.onDidClick(() => {
|
||||
// TODO: implement configuration dialog
|
||||
console.error('configuration dialog not implemented')
|
||||
});
|
||||
|
||||
await configureButton.updateCssStyles({ 'margin-top': '5px' });
|
||||
|
||||
toolBar.addToolbarItems([
|
||||
{
|
||||
component: reportTitle,
|
||||
toolbarSeparatorAfter: true
|
||||
},
|
||||
{
|
||||
component: timePeriod,
|
||||
toolbarSeparatorAfter: true
|
||||
},
|
||||
{
|
||||
component: configureButton
|
||||
}
|
||||
]);
|
||||
|
||||
return toolBar.component();
|
||||
}
|
||||
|
||||
protected abstract createViews(_view: azdata.ModelView): Promise<azdata.FlexContainer[]>;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as constants from '../common/constants';
|
||||
import { BaseQueryStoreReport } from './baseQueryStoreReport';
|
||||
import { QueryStoreView } from './queryStoreView';
|
||||
|
||||
|
||||
export class OverallResourceConsumption extends BaseQueryStoreReport {
|
||||
private duration: QueryStoreView;
|
||||
private executionCount: QueryStoreView;
|
||||
private cpuTime: QueryStoreView;
|
||||
private logicalReads: QueryStoreView;
|
||||
|
||||
constructor(extensionContext: vscode.ExtensionContext, databaseName: string) {
|
||||
super(constants.overallResourceConsumption, constants.overallResourceConsumptionToolbarLabel(databaseName), /*resizeable*/ false, extensionContext);
|
||||
this.duration = new QueryStoreView(constants.duration, 'chartreuse');
|
||||
this.executionCount = new QueryStoreView(constants.executionCount, 'coral');
|
||||
this.cpuTime = new QueryStoreView(constants.cpuTime, 'darkturquoise');
|
||||
this.logicalReads = new QueryStoreView(constants.logicalReads, 'forestgreen');
|
||||
}
|
||||
|
||||
public override async createViews(view: azdata.ModelView): Promise<azdata.FlexContainer[]> {
|
||||
const durationContainer = await this.duration.createViewContainer(view);
|
||||
const executionCountContainer = await this.executionCount.createViewContainer(view);
|
||||
const cpuTimeContainer = await this.cpuTime.createViewContainer(view);
|
||||
const logicalReadsContainer = await this.logicalReads.createViewContainer(view);
|
||||
|
||||
return [durationContainer, executionCountContainer, cpuTimeContainer, logicalReadsContainer];
|
||||
}
|
||||
}
|
||||
37
extensions/query-store/src/reports/queryStoreView.ts
Normal file
37
extensions/query-store/src/reports/queryStoreView.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { createOneComponentFlexContainer } from '../common/utils';
|
||||
|
||||
/**
|
||||
* Defines a view in a query store report
|
||||
*/
|
||||
export class QueryStoreView {
|
||||
// TODO: add toolbar support
|
||||
// TODO: add support for toggling between chart and table components (could potentially add a child class to support this).
|
||||
public component?: azdata.Component; // chart, query plan, text (component to display whole query text)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param title Title of view to display
|
||||
* @param backgroundColor TODO: remove this after chart components are supported
|
||||
*/
|
||||
constructor(private title: string, private backgroundColor: string) { }
|
||||
|
||||
/**
|
||||
* Creates component in a container with the background color. Eventually will create the component with a toolbar in a flex container
|
||||
* @param view
|
||||
* @returns
|
||||
*/
|
||||
public async createViewContainer(view: azdata.ModelView): Promise<azdata.FlexContainer> {
|
||||
// TODO: replace these text components with the actual chart/table/query plan components
|
||||
this.component = view.modelBuilder.text().withProps({
|
||||
value: this.title
|
||||
}).component();
|
||||
|
||||
return await createOneComponentFlexContainer(view, this.component, this.backgroundColor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as constants from '../common/constants';
|
||||
import { BaseQueryStoreReport } from './baseQueryStoreReport';
|
||||
import { QueryStoreView } from './queryStoreView';
|
||||
|
||||
export class TopResourceConsumingQueries extends BaseQueryStoreReport {
|
||||
private queries: QueryStoreView;
|
||||
private planSummary: QueryStoreView;
|
||||
private plan: QueryStoreView;
|
||||
|
||||
constructor(extensionContext: vscode.ExtensionContext, databaseName: string) {
|
||||
super(constants.topResourceConsumingQueries, constants.topResourceConsumingQueriesToolbarLabel(databaseName), /*resizeable*/ true, extensionContext);
|
||||
this.queries = new QueryStoreView(constants.queries, 'chartreuse');
|
||||
this.planSummary = new QueryStoreView(constants.planSummary('x'), 'coral'); // TODO: replace 'x' with actual query id
|
||||
this.plan = new QueryStoreView(constants.plan('x'), 'darkturquoise');
|
||||
}
|
||||
|
||||
public override async createViews(view: azdata.ModelView): Promise<azdata.FlexContainer[]> {
|
||||
const queriesContainer = await this.queries.createViewContainer(view);
|
||||
const planSummaryContainer = await this.planSummary.createViewContainer(view);
|
||||
const planContainer = await this.plan.createViewContainer(view);
|
||||
|
||||
return [queriesContainer, planSummaryContainer, planContainer];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user