Sql DB project dashboard (#14899)

* First set of changes for workspace dashboard implementing the toolbar

* Workspace dashboard container implementation (#14813)

* First set of changes for workspace dashboard implementing the toolbar (#14160)

* First set of changes for workspace dashboard implementing the toolbar

* Addressed comments

* Addressed one remaining comment

* Removed an extra comma in interfaces file

* Addressed comments

* Addressed comments

* Refactored a bit of code

* Remove unnecessary await

* Addressed comments

* First set of changes for workspace dashboard container

* Update targetPlatform icon+add Time column to deploy table

* Addressed comments

* Removed redundant class definition

* Addressed comments

* Addressed comments

* Change enum to union type in dataworkspace typings

* Fix tests

* Addressed comments
This commit is contained in:
Sakshi Sharma
2021-03-30 17:37:53 -07:00
committed by GitHub
parent 4df77c73bf
commit b774f09b6c
25 changed files with 855 additions and 25 deletions

View File

@@ -31,6 +31,10 @@ import { ISystemDatabaseReferenceSettings, IDacpacReferenceSettings, IProjectRef
import { DatabaseReferenceTreeItem } from '../models/tree/databaseReferencesTreeItem';
import { CreateProjectFromDatabaseDialog } from '../dialogs/createProjectFromDatabaseDialog';
import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry';
import { IconPathHelper } from '../common/iconHelper';
import { DashboardData, Status } from '../models/dashboardData/dashboardData';
const maxTableLength = 10;
/**
* Controller for managing lifecycle of projects
@@ -38,6 +42,8 @@ import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/t
export class ProjectsController {
private netCoreTool: NetCoreTool;
private buildHelper: BuildHelper;
private buildInfo: DashboardData[] = [];
private deployInfo: DashboardData[] = [];
projFileWatchers = new Map<string, vscode.FileSystemWatcher>();
@@ -46,6 +52,66 @@ export class ProjectsController {
this.buildHelper = new BuildHelper();
}
public get dashboardDeployData(): (string | dataworkspace.IconCellValue)[][] {
const infoRows: (string | dataworkspace.IconCellValue)[][] = [];
let count = 0;
for (let i = this.deployInfo.length - 1; i >= 0; i--) {
let icon: azdata.IconPath;
let text: string;
if (this.deployInfo[i].status === Status.success) {
icon = IconPathHelper.success;
text = constants.Success;
} else if (this.deployInfo[i].status === Status.failed) {
icon = IconPathHelper.error;
text = constants.Failed;
} else {
icon = IconPathHelper.inProgress;
text = constants.InProgress;
}
let infoRow: (string | dataworkspace.IconCellValue)[] = [count.toString(),
{ text: text, icon: icon },
this.deployInfo[i].target,
this.deployInfo[i].timeToCompleteAction,
this.deployInfo[i].startDate];
infoRows.push(infoRow);
count++;
}
return infoRows;
}
public get dashboardBuildData(): (string | dataworkspace.IconCellValue)[][] {
const infoRows: (string | dataworkspace.IconCellValue)[][] = [];
let count = 0;
for (let i = this.buildInfo.length - 1; i >= 0; i--) {
let icon: azdata.IconPath;
let text: string;
if (this.buildInfo[i].status === Status.success) {
icon = IconPathHelper.success;
text = constants.Success;
} else if (this.buildInfo[i].status === Status.failed) {
icon = IconPathHelper.error;
text = constants.Failed;
} else {
icon = IconPathHelper.inProgress;
text = constants.InProgress;
}
let infoRow: (string | dataworkspace.IconCellValue)[] = [count.toString(),
{ text: text, icon: icon },
this.buildInfo[i].target,
this.buildInfo[i].timeToCompleteAction,
this.buildInfo[i].startDate];
infoRows.push(infoRow);
count++;
}
return infoRows;
}
public refreshProjectsTree(workspaceTreeItem: dataworkspace.WorkspaceTreeItem): void {
(workspaceTreeItem.treeDataProvider as SqlDatabaseProjectTreeViewProvider).notifyTreeDataChanged();
}
@@ -108,6 +174,14 @@ export class ProjectsController {
const project: Project = this.getProjectFromContext(context);
const startTime = new Date();
const currentBuildTimeInfo = `${startTime.toLocaleDateString()} ${constants.at} ${startTime.toLocaleTimeString()}`;
let buildInfoNew = new DashboardData(Status.inProgress, project.getProjectTargetVersion(), currentBuildTimeInfo);
this.buildInfo.push(buildInfoNew);
if (this.buildInfo.length - 1 === maxTableLength) {
this.buildInfo.shift(); // Remove the first element to maintain the length
}
// Check mssql extension for project dlls (tracking issue #10273)
await this.buildHelper.createBuildDirFolder();
@@ -120,15 +194,26 @@ export class ProjectsController {
try {
await this.netCoreTool.runDotnetCommand(options);
const timeToBuild = new Date().getTime() - startTime.getTime();
const currentBuildIndex = this.buildInfo.findIndex(b => b.startDate === currentBuildTimeInfo);
this.buildInfo[currentBuildIndex].status = Status.success;
this.buildInfo[currentBuildIndex].timeToCompleteAction = utils.timeConversion(timeToBuild);
TelemetryReporter.createActionEvent(TelemetryViews.ProjectController, TelemetryActions.build)
.withAdditionalMeasurements({ duration: new Date().getTime() - startTime.getTime() })
.withAdditionalMeasurements({ duration: timeToBuild })
.send();
return project.dacpacOutputPath;
} catch (err) {
const timeToFailureBuild = new Date().getTime() - startTime.getTime();
const currentBuildIndex = this.buildInfo.findIndex(b => b.startDate === currentBuildTimeInfo);
this.buildInfo[currentBuildIndex].status = Status.failed;
this.buildInfo[currentBuildIndex].timeToCompleteAction = utils.timeConversion(timeToFailureBuild);
TelemetryReporter.createErrorEvent(TelemetryViews.ProjectController, TelemetryActions.build)
.withAdditionalMeasurements({ duration: new Date().getTime() - startTime.getTime() })
.withAdditionalMeasurements({ duration: timeToFailureBuild })
.send();
vscode.window.showErrorMessage(constants.projBuildFailed(utils.getErrorMessage(err)));
@@ -187,7 +272,16 @@ export class ProjectsController {
let result: mssql.DacFxResult;
telemetryProps.profileUsed = (settings.profileUsed ?? false).toString();
const actionStartTime = new Date().getTime();
const currentDate = new Date();
const actionStartTime = currentDate.getTime();
const currentDeployTimeInfo = `${currentDate.toLocaleDateString()} ${constants.at} ${currentDate.toLocaleTimeString()}`;
let deployInfoNew = new DashboardData(Status.inProgress, project.getProjectTargetVersion(), currentDeployTimeInfo);
this.deployInfo.push(deployInfoNew);
if (this.deployInfo.length - 1 === maxTableLength) {
this.deployInfo.shift(); // Remove the first element to maintain the length
}
try {
if ((<IPublishSettings>settings).upgradeExisting) {
@@ -200,20 +294,30 @@ export class ProjectsController {
}
} catch (err) {
const actionEndTime = new Date().getTime();
telemetryProps.actionDuration = (actionEndTime - actionStartTime).toString();
const timeToFailureDeploy = actionEndTime - actionStartTime;
telemetryProps.actionDuration = timeToFailureDeploy.toString();
telemetryProps.totalDuration = (actionEndTime - buildStartTime).toString();
TelemetryReporter.createErrorEvent(TelemetryViews.ProjectController, TelemetryActions.publishProject)
.withAdditionalProperties(telemetryProps)
.send();
const currentDeployIndex = this.deployInfo.findIndex(d => d.startDate === currentDeployTimeInfo);
this.deployInfo[currentDeployIndex].status = Status.failed;
this.deployInfo[currentDeployIndex].timeToCompleteAction = utils.timeConversion(timeToFailureDeploy);
throw err;
}
const actionEndTime = new Date().getTime();
telemetryProps.actionDuration = (actionEndTime - actionStartTime).toString();
const timeToDeploy = actionEndTime - actionStartTime;
telemetryProps.actionDuration = timeToDeploy.toString();
telemetryProps.totalDuration = (actionEndTime - buildStartTime).toString();
const currentDeployIndex = this.deployInfo.findIndex(d => d.startDate === currentDeployTimeInfo);
this.deployInfo[currentDeployIndex].status = Status.success;
this.deployInfo[currentDeployIndex].timeToCompleteAction = utils.timeConversion(timeToDeploy);
TelemetryReporter.createActionEvent(TelemetryViews.ProjectController, TelemetryActions.publishProject)
.withAdditionalProperties(telemetryProps)
.send();