mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
Initial changes for query store dashboard (#24272)
* create empty query store dashboard * add placeholder report content * cleanup * more cleanup
This commit is contained in:
@@ -33,13 +33,8 @@
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "queryStore.topResourceConsumingQueriesOpen",
|
||||
"title": "%queryStore.topResourceConsumingQueriesOpen%",
|
||||
"category": "%queryStore.category%"
|
||||
},
|
||||
{
|
||||
"command": "queryStore.overallResourceConsumptionOpen",
|
||||
"title": "%queryStore.overallResourceConsumptionOpen%",
|
||||
"command": "queryStore.openQueryStoreDashboard",
|
||||
"title": "%queryStore.openQueryStoreDashboard%",
|
||||
"category": "%queryStore.category%"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
"queryStore.displayName": "Query Store",
|
||||
"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"
|
||||
"queryStore.openQueryStoreDashboard": "Query Store"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import * as nls from 'vscode-nls';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
export function queryStoreDashboardTitle(databaseName: string): string { return localize('queryStoreDashboardTitle', "Query Store - {0}", databaseName); }
|
||||
|
||||
export const overallResourceConsumption = localize('overallResourceConsumption', "Overall Resource Consumption");
|
||||
export const duration = localize('duration', "Duration");
|
||||
export const executionCount = localize('executionCount', "Execution Count");
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { TopResourceConsumingQueries } from './reports/topResourceConsumingQueries';
|
||||
import { OverallResourceConsumption } from './reports/overallResourceConsumption';
|
||||
import { QueryStoreDashboard } from './reports/queryStoreDashboard';
|
||||
|
||||
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() }));
|
||||
// TODO: add OE entry point with condition for command to only be visible for db's with Query Store enabled (or consider always showing and having a way to enable when dashboard is opened?)
|
||||
// TODO: remove entry point from command palette - keeping for now to speed up testing so a connection doesn't need to be made to launch the dashboard
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryStore.openQueryStoreDashboard', async () => { await new QueryStoreDashboard('AdventureWorks', context).open() }));
|
||||
}
|
||||
|
||||
export function deactivate(): void {
|
||||
|
||||
@@ -11,40 +11,35 @@ import * as constants from '../common/constants';
|
||||
import { ConfigureDialog } from '../settings/configureDialog';
|
||||
|
||||
export abstract class BaseQueryStoreReport {
|
||||
protected editor: azdata.workspace.ModelViewEditor;
|
||||
protected flexModel?: azdata.FlexContainer;
|
||||
protected configureDialog?: ConfigureDialog;
|
||||
protected configureButton?: azdata.ButtonComponent;
|
||||
|
||||
constructor(reportName: string, private reportTitle: string, protected resizeable: boolean, private extensionContext: vscode.ExtensionContext) {
|
||||
this.editor = azdata.workspace.createModelViewEditor(reportName, { retainContextWhenHidden: true, supportsSave: false }, reportName);
|
||||
constructor(private reportTitle: string, protected resizeable: boolean, private extensionContext: vscode.ExtensionContext) { }
|
||||
|
||||
public get ReportContent(): azdata.FlexContainer | undefined {
|
||||
return this.flexModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and opens the report
|
||||
*/
|
||||
public async open(): Promise<void> {
|
||||
this.editor.registerContent(async (view) => {
|
||||
this.flexModel = <azdata.FlexContainer>view.modelBuilder.flexContainer().component();
|
||||
public async createReport(view: azdata.ModelView): Promise<void> {
|
||||
this.flexModel = <azdata.FlexContainer>view.modelBuilder.flexContainer().component();
|
||||
|
||||
const toolbar = await this.createToolbar(view);
|
||||
this.flexModel.addItem(toolbar, { flex: 'none' });
|
||||
const toolbar = await this.createToolbar(view);
|
||||
this.flexModel.addItem(toolbar, { flex: 'none' });
|
||||
|
||||
const views = await this.createViews(view);
|
||||
const views = await this.createViews(view);
|
||||
|
||||
const mainContainer = await this.createMainContainer(view, views);
|
||||
const mainContainer = await this.createMainContainer(view, views);
|
||||
|
||||
this.flexModel.addItem(mainContainer, { CSSStyles: { 'width': '100%', 'height': '100%' } });
|
||||
this.flexModel.addItem(mainContainer, { CSSStyles: { 'width': '100%', 'height': '100%' } });
|
||||
|
||||
this.flexModel.setLayout({
|
||||
flexFlow: 'column',
|
||||
height: '100%'
|
||||
});
|
||||
|
||||
await view.initializeModel(this.flexModel);
|
||||
this.flexModel.setLayout({
|
||||
flexFlow: 'column',
|
||||
height: '100%'
|
||||
});
|
||||
|
||||
await this.editor.openEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,7 @@ export class OverallResourceConsumption extends BaseQueryStoreReport {
|
||||
private logicalReads: QueryStoreView;
|
||||
|
||||
constructor(extensionContext: vscode.ExtensionContext, databaseName: string) {
|
||||
super(constants.overallResourceConsumption, constants.overallResourceConsumptionToolbarLabel(databaseName), /*resizeable*/ false, extensionContext);
|
||||
super(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');
|
||||
|
||||
48
extensions/query-store/src/reports/queryStoreDashboard.ts
Normal file
48
extensions/query-store/src/reports/queryStoreDashboard.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 constants from '../common/constants';
|
||||
import { TopResourceConsumingQueries } from './topResourceConsumingQueries';
|
||||
import { OverallResourceConsumption } from './overallResourceConsumption';
|
||||
|
||||
export class QueryStoreDashboard {
|
||||
constructor(private dbName: string, private extensionContext: vscode.ExtensionContext) { }
|
||||
|
||||
/**
|
||||
* Creates and opens the report
|
||||
*/
|
||||
public async open(): Promise<void> {
|
||||
// TODO: update title based on selected tab to have the current selected report in editor tab title
|
||||
const dashboard = azdata.window.createModelViewDashboard(constants.queryStoreDashboardTitle(this.dbName));
|
||||
dashboard.registerTabs(async (view: azdata.ModelView) => {
|
||||
const topResourceConsumingQueriesReport = new TopResourceConsumingQueries(this.extensionContext, this.dbName);
|
||||
const overallResourceConsumptionReport = new OverallResourceConsumption(this.extensionContext, this.dbName);
|
||||
|
||||
await Promise.all([topResourceConsumingQueriesReport.createReport(view), overallResourceConsumptionReport.createReport(view)]);
|
||||
|
||||
const topResourceConsumingQueriesTab: azdata.DashboardTab = {
|
||||
id: 'TopResourceConsumingQueriesTab',
|
||||
content: topResourceConsumingQueriesReport.ReportContent!,
|
||||
title: constants.topResourceConsumingQueries
|
||||
};
|
||||
|
||||
const overallResourceConsumptionTab: azdata.DashboardTab = {
|
||||
id: 'OverallResourceConsumptionTab',
|
||||
content: overallResourceConsumptionReport.ReportContent!,
|
||||
title: constants.overallResourceConsumption
|
||||
};
|
||||
|
||||
return [
|
||||
overallResourceConsumptionTab,
|
||||
topResourceConsumingQueriesTab
|
||||
];
|
||||
});
|
||||
|
||||
await dashboard.open();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export class TopResourceConsumingQueries extends BaseQueryStoreReport {
|
||||
private plan: QueryStoreView;
|
||||
|
||||
constructor(extensionContext: vscode.ExtensionContext, databaseName: string) {
|
||||
super(constants.topResourceConsumingQueries, constants.topResourceConsumingQueriesToolbarLabel(databaseName), /*resizeable*/ true, extensionContext);
|
||||
super(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');
|
||||
|
||||
Reference in New Issue
Block a user