From addef2d5848442c3aacace8e5eaae4cb4a686d39 Mon Sep 17 00:00:00 2001
From: Sakshi Sharma <57200045+SakshiS-harma@users.noreply.github.com>
Date: Wed, 7 Apr 2021 00:42:11 -0700
Subject: [PATCH] Add message when no history exists on projects dashboard
(#15002)
* Add message when no history exists on projects dashboard
* Bump version for sql db projects
* Update text, add refresh button
* Remove commented code
---
extensions/data-workspace/images/refresh.svg | 3 +
.../data-workspace/src/common/constants.ts | 4 +
.../data-workspace/src/common/iconHelper.ts | 2 +
.../src/dialogs/projectDashboard.ts | 130 +++++++++++-------
extensions/sql-database-projects/package.json | 4 +-
5 files changed, 89 insertions(+), 54 deletions(-)
create mode 100644 extensions/data-workspace/images/refresh.svg
diff --git a/extensions/data-workspace/images/refresh.svg b/extensions/data-workspace/images/refresh.svg
new file mode 100644
index 0000000000..f03579110b
--- /dev/null
+++ b/extensions/data-workspace/images/refresh.svg
@@ -0,0 +1,3 @@
+
diff --git a/extensions/data-workspace/src/common/constants.ts b/extensions/data-workspace/src/common/constants.ts
index ebb2731836..fbddd579c7 100644
--- a/extensions/data-workspace/src/common/constants.ts
+++ b/extensions/data-workspace/src/common/constants.ts
@@ -23,6 +23,7 @@ export const DoNotShowAgain = localize('dataworkspace.doNotShowAgain', "Do not s
export const ProjectsFailedToLoad = localize('dataworkspace.projectsFailedToLoad', "Some projects failed to load. Please open console for more information");
export const fileDoesNotExist = (name: string): string => { return localize('fileDoesNotExist', "File '{0}' doesn't exist", name); };
export const projectNameNull = localize('projectNameNull', "Project name is null");
+export const noPreviousData = (tableName: string): string => { return localize('noPreviousData', "Prior {0} will appear here, please run to see the results.", tableName); };
// config settings
export const projectsConfigurationKey = 'projects';
@@ -75,6 +76,9 @@ export const LocalClonePathPlaceholder = localize('dataworkspace.localClonePathP
export const ProjectConfigurationKey = 'projects';
export const ProjectSaveLocationKey = 'defaultProjectSaveLocation';
+// Dashboard dialog
+export const Refresh = localize('dataworksapce.refresh', 'Refresh');
+
export namespace cssStyles {
export const title = { 'font-size': '18px', 'font-weight': '600' };
export const tableHeader = { 'text-align': 'left', 'font-weight': '500', 'font-size': '13px', 'user-select': 'text' };
diff --git a/extensions/data-workspace/src/common/iconHelper.ts b/extensions/data-workspace/src/common/iconHelper.ts
index eef61bb913..1d3b22a48f 100644
--- a/extensions/data-workspace/src/common/iconHelper.ts
+++ b/extensions/data-workspace/src/common/iconHelper.ts
@@ -13,11 +13,13 @@ export interface IconPath {
export class IconPathHelper {
private static extensionContext: vscode.ExtensionContext;
public static folder: IconPath;
+ public static refresh: IconPath;
public static setExtensionContext(extensionContext: vscode.ExtensionContext) {
IconPathHelper.extensionContext = extensionContext;
IconPathHelper.folder = IconPathHelper.makeIcon('folder', true);
+ IconPathHelper.refresh = IconPathHelper.makeIcon('refresh', true);
}
private static makeIcon(name: string, sameIcon: boolean = false) {
diff --git a/extensions/data-workspace/src/dialogs/projectDashboard.ts b/extensions/data-workspace/src/dialogs/projectDashboard.ts
index a5fbda817a..9280d526bd 100644
--- a/extensions/data-workspace/src/dialogs/projectDashboard.ts
+++ b/extensions/data-workspace/src/dialogs/projectDashboard.ts
@@ -8,6 +8,7 @@ import { IDashboardColumnInfo, IDashboardTable, IProjectAction, IProjectActionGr
import * as path from 'path';
import * as vscode from 'vscode';
import * as constants from '../common/constants';
+import { IconPathHelper } from '../common/iconHelper';
import { IWorkspaceService } from '../common/interfaces';
import { fileExist } from '../common/utils';
@@ -17,6 +18,8 @@ export class ProjectDashboard {
private modelView: azdata.ModelView | undefined;
private projectProvider: IProjectProvider | undefined;
private overviewTab: azdata.DashboardTab | undefined;
+ private rootContainer: azdata.FlexContainer | undefined;
+ private tableContainer: azdata.Component | undefined;
constructor(private _workspaceService: IWorkspaceService, private _treeItem: WorkspaceTreeItem) {
}
@@ -69,17 +72,32 @@ export class ProjectDashboard {
projectActions.forEach((action, actionIndex) => {
if (this.isProjectAction(action)) {
const button = this.createButton(action);
- buttons.push({ component: button });
+ buttons.push({ component: button, toolbarSeparatorAfter: (projectActionsLength - 1 === actionIndex) });
} else {
const groupLength = action.actions.length;
action.actions.forEach((groupAction, index) => {
const button = this.createButton(groupAction);
- buttons.push({ component: button, toolbarSeparatorAfter: ((groupLength - 1 === index) && (projectActionsLength - 1 !== actionIndex)) }); // Add toolbar separator at the end of the group, if the group is not the last in the list
+ buttons.push({ component: button, toolbarSeparatorAfter: ((groupLength - 1 === index) || (projectActionsLength - 1 === actionIndex)) }); // Add toolbar separator at the end of the group
});
}
});
+ const refreshButton = this.modelView!.modelBuilder.button()
+ .withProperties({
+ label: constants.Refresh,
+ iconPath: IconPathHelper.refresh,
+ height: '20px'
+ }).component();
+
+ refreshButton.onDidClick(() => {
+ this.rootContainer?.removeItem(this.tableContainer!);
+ this.tableContainer = this.createTables();
+ this.rootContainer?.addItem(this.tableContainer);
+ });
+
+ buttons.push({ component: refreshButton });
+
return this.modelView!.modelBuilder.toolbarContainer()
.withToolbarItems(
buttons
@@ -106,7 +124,7 @@ export class ProjectDashboard {
}
private createContainer(title: string, location: string): azdata.FlexContainer {
- const rootContainer = this.modelView!.modelBuilder.flexContainer().withLayout(
+ this.rootContainer = this.modelView!.modelBuilder.flexContainer().withLayout(
{
flexFlow: 'column',
width: '100%',
@@ -114,12 +132,12 @@ export class ProjectDashboard {
}).component();
const headerContainer = this.createHeader(title, location);
- const tableContainer = this.createTables();
+ this.tableContainer = this.createTables();
- rootContainer.addItem(headerContainer);
- rootContainer.addItem(tableContainer);
+ this.rootContainer.addItem(headerContainer);
+ this.rootContainer.addItem(this.tableContainer);
- return rootContainer;
+ return this.rootContainer;
}
/**
@@ -186,54 +204,62 @@ export class ProjectDashboard {
.component();
tableContainer.addItem(tableNameLabel, { CSSStyles: { 'padding-left': '25px', 'padding-bottom': '20px', ...constants.cssStyles.title } });
- const columns: azdata.DeclarativeTableColumn[] = [];
- info.columns.forEach((column: IDashboardColumnInfo) => {
- let col = {
- displayName: column.displayName,
- valueType: column.type === 'icon' ? azdata.DeclarativeDataType.component : azdata.DeclarativeDataType.string,
- isReadOnly: true,
- width: column.width,
- headerCssStyles: {
- 'border': 'none',
- ...constants.cssStyles.tableHeader
- },
- rowCssStyles: {
- ...constants.cssStyles.tableRow
- },
- };
- columns.push(col);
- });
-
- const data: azdata.DeclarativeTableCellValue[][] = [];
- info.data.forEach(values => {
- const columnValue: azdata.DeclarativeTableCellValue[] = [];
- values.forEach(val => {
- if (typeof val === 'string') {
- columnValue.push({ value: val });
- } else {
- const iconComponent = this.modelView!.modelBuilder.image().withProperties({
- iconPath: val.icon,
- width: '15px',
- height: '15px',
- iconHeight: '15px',
- iconWidth: '15px'
- }).component();
- const stringComponent = this.modelView!.modelBuilder.text().withProperties({
- value: val.text,
- CSSStyles: { 'margin-block-start': 'auto', 'block-size': 'auto', 'margin-block-end': '0px' }
- }).component();
-
- const columnData = this.modelView!.modelBuilder.flexContainer().withItems([iconComponent, stringComponent], { flex: '0 0 auto', CSSStyles: { 'margin-right': '10px' } }).withLayout({ flexFlow: 'row' }).component();
- columnValue.push({ value: columnData });
- }
+ if (info.data.length === 0) {
+ const noDataText = constants.noPreviousData(info.name.toLocaleLowerCase());
+ const noDataLabel = this.modelView!.modelBuilder.text()
+ .withProperties({ value: noDataText })
+ .component();
+ tableContainer.addItem(noDataLabel, { CSSStyles: { 'padding-left': '25px', 'padding-bottom': '20px' } });
+ } else {
+ const columns: azdata.DeclarativeTableColumn[] = [];
+ info.columns.forEach((column: IDashboardColumnInfo) => {
+ let col = {
+ displayName: column.displayName,
+ valueType: column.type === 'icon' ? azdata.DeclarativeDataType.component : azdata.DeclarativeDataType.string,
+ isReadOnly: true,
+ width: column.width,
+ headerCssStyles: {
+ 'border': 'none',
+ ...constants.cssStyles.tableHeader
+ },
+ rowCssStyles: {
+ ...constants.cssStyles.tableRow
+ },
+ };
+ columns.push(col);
});
- data.push(columnValue);
- });
- const table = this.modelView!.modelBuilder.declarativeTable()
- .withProperties({ columns: columns, dataValues: data, ariaLabel: info.name, CSSStyles: { 'margin-left': '30px' } }).component();
+ const data: azdata.DeclarativeTableCellValue[][] = [];
+ info.data.forEach(values => {
+ const columnValue: azdata.DeclarativeTableCellValue[] = [];
+ values.forEach(val => {
+ if (typeof val === 'string') {
+ columnValue.push({ value: val });
+ } else {
+ const iconComponent = this.modelView!.modelBuilder.image().withProperties({
+ iconPath: val.icon,
+ width: '15px',
+ height: '15px',
+ iconHeight: '15px',
+ iconWidth: '15px'
+ }).component();
+ const stringComponent = this.modelView!.modelBuilder.text().withProperties({
+ value: val.text,
+ CSSStyles: { 'margin-block-start': 'auto', 'block-size': 'auto', 'margin-block-end': '0px' }
+ }).component();
- tableContainer.addItem(table);
+ const columnData = this.modelView!.modelBuilder.flexContainer().withItems([iconComponent, stringComponent], { flex: '0 0 auto', CSSStyles: { 'margin-right': '10px' } }).withLayout({ flexFlow: 'row' }).component();
+ columnValue.push({ value: columnData });
+ }
+ });
+ data.push(columnValue);
+ });
+
+ const table = this.modelView!.modelBuilder.declarativeTable()
+ .withProperties({ columns: columns, dataValues: data, ariaLabel: info.name, CSSStyles: { 'margin-left': '30px' } }).component();
+
+ tableContainer.addItem(table);
+ }
});
return tableContainer;
}
diff --git a/extensions/sql-database-projects/package.json b/extensions/sql-database-projects/package.json
index 9c4c935ab5..1e9964d8d1 100644
--- a/extensions/sql-database-projects/package.json
+++ b/extensions/sql-database-projects/package.json
@@ -2,12 +2,12 @@
"name": "sql-database-projects",
"displayName": "SQL Database Projects",
"description": "The SQL Database Projects extension for Azure Data Studio allows users to develop and publish database schemas.",
- "version": "0.8.0",
+ "version": "0.8.1",
"publisher": "Microsoft",
"preview": true,
"engines": {
"vscode": "^1.30.1",
- "azdata": ">=1.27.0"
+ "azdata": ">=1.28.0"
},
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
"icon": "images/sqlDatabaseProjects.png",