Adding new filter icon (#20762)

This commit is contained in:
Aasim Khan
2022-10-06 21:34:21 -07:00
committed by GitHub
parent 00ff3ac50f
commit 9f5ee32825
11 changed files with 85 additions and 20 deletions

View File

@@ -138,6 +138,9 @@ export class AzdataGraphView {
*/
public zoomToFit(): void {
this._diagram.zoomToFit();
if (this.getZoomLevel() > 200) {
this.setZoomLevel(200);
}
}
/**

View File

@@ -13,7 +13,7 @@ import { ExecutionPlanComparisonEditorView } from 'sql/workbench/contrib/executi
export class ExecutionPlanComparisonInput extends EditorInput {
public static ID: string = 'workbench.editorinputs.compareExecutionPlanInput';
public static SCHEME: string = 'compareExecutionPlanInput';
private readonly editorNamePrefix = localize('epCompare.editorName', "Compare Execution Plans");
private readonly editorNamePrefix = localize('epCompare.editorName', "CompareExecutionPlans");
private _editorName: string;
// Caching the views for faster tab switching
@@ -27,11 +27,11 @@ export class ExecutionPlanComparisonInput extends EditorInput {
// Getting name for the editor
const existingNames = this._editorService.editors.map(editor => editor.getName());
let i = 0;
this._editorName = `${this.editorNamePrefix} ${i}`;
let i = 1;
this._editorName = `${this.editorNamePrefix}_${i}`;
while (existingNames.includes(this._editorName)) {
i++;
this._editorName = `${this.editorNamePrefix} ${i}`;
this._editorName = `${this.editorNamePrefix}_${i}`;
}
}

View File

@@ -271,6 +271,7 @@ export const openQueryIconClassNames = 'ep-open-query-icon';
export const openPlanFileIconClassNames = 'ep-open-plan-file-icon';
export const saveIconClassNames = 'ep-save-icon';
export const searchIconClassNames = 'ep-search-icon';
export const filterIconClassNames = 'ep-filter-icon';
export const sortAlphabeticallyIconClassNames = 'ep-sort-alphabetically-icon';
export const sortReverseAlphabeticallyIconClassNames = 'ep-sort-reverse-alphabetically-icon';
export const sortByDisplayOrderIconClassNames = 'ep-sort-display-order-icon';

View File

@@ -19,7 +19,7 @@ import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticip
import * as DOM from 'vs/base/browser/dom';
import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { localize } from 'vs/nls';
import { addIconClassName, openPropertiesIconClassNames, polygonBorderColor, polygonFillColor, resetZoomIconClassName, searchIconClassNames, splitScreenHorizontallyIconClassName, splitScreenVerticallyIconClassName, zoomInIconClassNames, zoomOutIconClassNames, zoomToFitIconClassNames } from 'sql/workbench/contrib/executionPlan/browser/constants';
import { addIconClassName, disableTooltipIconClassName, enableTooltipIconClassName, openPropertiesIconClassNames, polygonBorderColor, polygonFillColor, resetZoomIconClassName, searchIconClassNames, splitScreenHorizontallyIconClassName, splitScreenVerticallyIconClassName, zoomInIconClassNames, zoomOutIconClassNames, zoomToFitIconClassNames } from 'sql/workbench/contrib/executionPlan/browser/constants';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { extname } from 'vs/base/common/path';
import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -49,6 +49,7 @@ export class ExecutionPlanComparisonEditorView {
private _toggleOrientationAction: Action;
private _searchNodeAction: Action;
private _searchNodeActionForAddedPlan: Action;
private _toggleTooltipAction: Action;
private _planComparisonContainer: HTMLElement;
@@ -104,6 +105,7 @@ export class ExecutionPlanComparisonEditorView {
private _bottomPlanRecommendations: ExecutionPlanViewHeader;
private _bottomSimilarNode: Map<string, azdata.executionPlan.ExecutionGraphComparisonResult> = new Map();
private _latestRequestUuid: string;
private _areTooltipsEnabled: boolean = true;
public get activeBottomPlanDiagram(): AzdataGraphView | undefined {
if (this.bottomPlanDiagrams.length > 0) {
@@ -153,6 +155,7 @@ export class ExecutionPlanComparisonEditorView {
this._searchNodeAction = this._instantiationService.createInstance(SearchNodeAction, PlanIdentifier.Primary);
this._searchNodeActionForAddedPlan = this._instantiationService.createInstance(SearchNodeAction, PlanIdentifier.Added);
this._resetZoomAction = new ZoomReset();
this._toggleTooltipAction = new ActionBarToggleTooltip();
const content: ITaskbarContent[] = [
{ action: this._addExecutionPlanAction },
{ action: this._zoomInAction },
@@ -162,7 +165,8 @@ export class ExecutionPlanComparisonEditorView {
{ action: this._toggleOrientationAction },
{ action: this._propertiesAction },
{ action: this._searchNodeAction },
{ action: this._searchNodeActionForAddedPlan }
{ action: this._searchNodeActionForAddedPlan },
{ action: this._toggleTooltipAction }
];
this._taskbar.setContent(content);
this.container.appendChild(this._taskbarContainer);
@@ -407,6 +411,9 @@ export class ExecutionPlanComparisonEditorView {
this._propertiesView.setSecondaryElement(executionPlanGraphs[0].root);
this._addExecutionPlanAction.enabled = false;
this._searchNodeActionForAddedPlan.enabled = true;
if (!this._areTooltipsEnabled) {
this.activeBottomPlanDiagram.toggleTooltip();
}
}
this.refreshSplitView();
}
@@ -481,6 +488,18 @@ export class ExecutionPlanComparisonEditorView {
this._propertiesContainer.style.display = this._propertiesContainer.style.display === 'none' ? '' : 'none';
}
public toggleTooltips(): boolean {
let state: boolean;
if (this.activeTopPlanDiagram) {
state = this.activeTopPlanDiagram.toggleTooltip();
}
if (this.activeBottomPlanDiagram) {
state = this.activeBottomPlanDiagram.toggleTooltip();
}
this._areTooltipsEnabled = state;
return state;
}
public toggleOrientation(): void {
if (this._orientation === 'vertical') {
this._sashContainer.style.width = '100%';
@@ -680,6 +699,27 @@ class PropertiesAction extends Action {
}
}
export class ActionBarToggleTooltip extends Action {
public static ID = 'ep.tooltipToggleActionBar';
public static WHEN_TOOLTIPS_ENABLED_LABEL = localize('executionPlanEnableTooltip', "Tooltips enabled");
public static WHEN_TOOLTIPS_DISABLED_LABEL = localize('executionPlanDisableTooltip', "Tooltips disabled");
constructor() {
super(ActionBarToggleTooltip.ID, ActionBarToggleTooltip.WHEN_TOOLTIPS_ENABLED_LABEL, enableTooltipIconClassName);
}
public override async run(context: ExecutionPlanComparisonEditorView): Promise<void> {
const state = context.toggleTooltips();
if (!state) {
this.class = disableTooltipIconClassName;
this.label = ActionBarToggleTooltip.WHEN_TOOLTIPS_DISABLED_LABEL;
} else {
this.class = enableTooltipIconClassName;
this.label = ActionBarToggleTooltip.WHEN_TOOLTIPS_ENABLED_LABEL;
}
}
}
enum PlanIdentifier {
Primary = 0,
Added = 1

View File

@@ -379,10 +379,14 @@ export class ExecutionPlanComparisonPropertiesView extends ExecutionPlanProperti
diffIcon.title = notEqualTitle;
break;
case sqlExtHostType.executionPlan.ExecutionPlanGraphElementPropertyDataType.Number:
diffIcon = (parseFloat(v.primaryProp.displayValue) > parseFloat(v.secondaryProp.displayValue))
? { iconClass: Codicon.chevronRight.classNames, title: greaterThanTitle }
: { iconClass: Codicon.chevronLeft.classNames, title: lessThanTitle };
if (v.primaryProp.betterValue === sqlExtHostType.executionPlan.ExecutionPlanGraphElementPropertyBetterValue.None) {
diffIcon.title = notEqualTitle;
diffIcon.iconClass = executionPlanComparisonPropertiesDifferent;
} else {
diffIcon = (parseFloat(v.primaryProp.displayValue) > parseFloat(v.secondaryProp.displayValue))
? { iconClass: Codicon.chevronRight.classNames, title: greaterThanTitle }
: { iconClass: Codicon.chevronLeft.classNames, title: lessThanTitle };
}
break;
case sqlExtHostType.executionPlan.ExecutionPlanGraphElementPropertyDataType.String:
diffIcon.iconClass = executionPlanComparisonPropertiesDifferent;

View File

@@ -10,7 +10,7 @@ import { localize } from 'vs/nls';
import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
import { Codicon } from 'vs/base/common/codicons';
import { propertiesSearchDescription, searchIconClassNames, searchPlaceholder, sortAlphabeticallyIconClassNames, sortByDisplayOrderIconClassNames, sortReverseAlphabeticallyIconClassNames } from 'sql/workbench/contrib/executionPlan/browser/constants';
import { filterIconClassNames, propertiesSearchDescription, searchPlaceholder, sortAlphabeticallyIconClassNames, sortByDisplayOrderIconClassNames, sortReverseAlphabeticallyIconClassNames } from 'sql/workbench/contrib/executionPlan/browser/constants';
import { attachInputBoxStyler, attachTableStyler } from 'sql/platform/theme/common/styler';
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/common/constants';
import { contrastBorder, inputBackground, listHoverBackground, listInactiveSelectionBackground } from 'vs/platform/theme/common/colorRegistry';
@@ -127,13 +127,13 @@ export abstract class ExecutionPlanPropertiesViewBase extends Disposable impleme
], { icon: true, label: false });
this._propertiesSearchInputContainer = DOM.$('.table-search');
this._propertiesSearchInputContainer.classList.add('codicon', searchIconClassNames);
this._propertiesSearchInputContainer.classList.add('codicon', filterIconClassNames);
this._propertiesSearchInput = this._register(new InputBox(this._propertiesSearchInputContainer, this._contextViewService, {
ariaDescription: propertiesSearchDescription,
placeholder: searchPlaceholder
}));
attachInputBoxStyler(this._propertiesSearchInput, this._themeService);
this._propertiesSearchInput.element.classList.add('codicon', searchIconClassNames);
this._propertiesSearchInput.element.classList.add('codicon', filterIconClassNames);
this._searchAndActionBarContainer.appendChild(this._propertiesSearchInputContainer);
this._register(this._propertiesSearchInput.onDidChange(e => {
this.searchTable(e);
@@ -331,7 +331,7 @@ export abstract class ExecutionPlanPropertiesViewBase extends Disposable impleme
} else if (rawDataValue !== undefined) {
dataValue = rawDataValue.text ?? rawDataValue.title;
}
if (dataValue.toLowerCase().includes(search.toLowerCase())) {
if (dataValue?.toLowerCase().includes(search.toLowerCase())) {
includeRow = true;
break;
}

View File

@@ -267,14 +267,11 @@ export class ExecutionPlanView implements ISashLayoutProvider {
* use the scroll bars.
*/
diagramContainer.addEventListener('wheel', e => {
this._parent.scrollTop += e.deltaY;
//Hiding all tooltips when we scroll.
const element = document.getElementsByClassName('mxTooltip');
for (let i = 0; i < element.length; i++) {
(<HTMLElement>element[i]).style.visibility = 'hidden';
}
e.preventDefault();
e.stopPropagation();
});
this._planContainer.appendChild(diagramContainer);

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{fill:#F6F6F6;} .icon-vs-bg{fill:#424242;} .icon-vs-fg{fill:#F0EFF1;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M0 0v3.043l5 6v6.957h6v-6.957l5-6v-3.043h-16z" id="outline"/><path class="icon-vs-fg" d="M7 14h2v-5.681l5-6v-.319h-12v.319l5 6v5.681z" id="iconFg"/><path class="icon-vs-bg" d="M10 15h-4v-6.319l-5-6v-1.681h14v1.681l-5 6v6.319zm-3-1h2v-5.681l5-6v-.319h-12v.319l5 6v5.681z" id="iconBg"/></svg>

After

Width:  |  Height:  |  Size: 652 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#0000;} .icon-vs-out{fill:#0000;} .icon-vs-bg{fill:#F6F6F6;} .icon-vs-fg{fill:#0000;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M0 0v3.043l5 6v6.957h6v-6.957l5-6v-3.043h-16z" id="outline"/><path class="icon-vs-fg" d="M7 14h2v-5.681l5-6v-.319h-12v.319l5 6v5.681z" id="iconFg"/><path class="icon-vs-bg" d="M10 15h-4v-6.319l-5-6v-1.681h14v1.681l-5 6v6.319zm-3-1h2v-5.681l5-6v-.319h-12v.319l5 6v5.681z" id="iconBg"/></svg>

After

Width:  |  Height:  |  Size: 647 B

View File

@@ -390,6 +390,24 @@ However we always want it to be the width of the container it is resizing.
background-repeat: no-repeat;
}
.eps-container .ep-filter-icon,
.top-operations-tab .ep-filter-icon {
background-image: url(../images/actionIcons/filter.svg);
background-size: 16px 16px;
background-position: center;
background-repeat: no-repeat;
}
.vs-dark .eps-container .ep-filter-icon,
.hc-black .eps-container .ep-filter-icon,
.vs-dark .top-operations-tab .ep-filter-icon,
.hc-black .top-operations-tab .ep-filter-icon {
background-image: url(../images/actionIcons/filterDark.svg);
background-size: 16px 16px;
background-position: center;
background-repeat: no-repeat;
}
.eps-container .ep-sort-alphabetically-icon {
background-image: url(../images/actionIcons/sortAlphabetically.svg);
background-size: 16px 16px;

View File

@@ -29,7 +29,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
import { ITableKeyboardEvent } from 'sql/base/browser/ui/table/interfaces';
import { Disposable } from 'vs/base/common/lifecycle';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import { searchIconClassNames, searchPlaceholder, topOperationsSearchDescription } from 'sql/workbench/contrib/executionPlan/browser/constants';
import { filterIconClassNames, searchPlaceholder, topOperationsSearchDescription } from 'sql/workbench/contrib/executionPlan/browser/constants';
const TABLE_SORT_COLUMN_KEY = 'tableCostColumnForSorting';
@@ -163,14 +163,14 @@ export class TopOperationsTabView extends Disposable implements IPanelView {
const headerSearchBarContainer = DOM.$('.top-operations-header-search-bar');
headerContainer.appendChild(headerSearchBarContainer);
headerContainer.classList.add('codicon', searchIconClassNames);
headerContainer.classList.add('codicon', filterIconClassNames);
const topOperationsSearchInput = new InputBox(headerSearchBarContainer, this._contextViewService, {
ariaDescription: topOperationsSearchDescription,
placeholder: searchPlaceholder
});
attachInputBoxStyler(topOperationsSearchInput, this._themeService);
topOperationsSearchInput.element.classList.add('codicon', searchIconClassNames);
topOperationsSearchInput.element.classList.add('codicon', filterIconClassNames);
const header = this._instantiationService.createInstance(ExecutionPlanViewHeader, headerInfoContainer, {
planIndex: index,