Hyperlink Component improvements (#10330)

* Hyperlink Component improvements

* Remove hyperlink CSS styles
This commit is contained in:
Charles Gagnon
2020-05-08 16:49:07 -07:00
committed by GitHub
parent f220f6486a
commit 2893659983
5 changed files with 46 additions and 31 deletions

View File

@@ -59,7 +59,6 @@ export class IconPathHelper {
export namespace cssStyles { export namespace cssStyles {
export const title = { 'font-size': '14px', 'font-weight': '600' }; export const title = { 'font-size': '14px', 'font-weight': '600' };
export const tableHeader = { 'text-align': 'left', 'font-weight': 'bold', 'text-transform': 'uppercase', 'font-size': '10px', 'user-select': 'text' }; export const tableHeader = { 'text-align': 'left', 'font-weight': 'bold', 'text-transform': 'uppercase', 'font-size': '10px', 'user-select': 'text' };
export const hyperlink = { 'user-select': 'text', 'color': '#0078d4', 'text-decoration': 'underline', 'cursor': 'pointer' };
export const text = { 'margin-block-start': '0px', 'margin-block-end': '0px' }; export const text = { 'margin-block-start': '0px', 'margin-block-end': '0px' };
export const overflowEllipsisText = { ...text, 'overflow': 'hidden', 'text-overflow': 'ellipsis' }; export const overflowEllipsisText = { ...text, 'overflow': 'hidden', 'text-overflow': 'ellipsis' };
export const nonSelectableText = { ...cssStyles.text, 'user-select': 'none' }; export const nonSelectableText = { ...cssStyles.text, 'user-select': 'none' };

View File

@@ -363,7 +363,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
.withProperties<azdata.HyperlinkComponentProperties>({ .withProperties<azdata.HyperlinkComponentProperties>({
label: getServiceNameDisplayText(serviceStatus.serviceName), label: getServiceNameDisplayText(serviceStatus.serviceName),
url: '', url: '',
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } CSSStyles: { ...cssStyles.text }
}).component(); }).component();
nameCell.onDidClick(() => { nameCell.onDidClick(() => {
this.dashboard.switchToServiceTab(serviceStatus.serviceName); this.dashboard.switchToServiceTab(serviceStatus.serviceName);
@@ -458,7 +458,7 @@ function createEndpointComponent(modelBuilder: azdata.ModelBuilder, endpoint: En
.withProperties<azdata.HyperlinkComponentProperties>({ .withProperties<azdata.HyperlinkComponentProperties>({
label: endpoint.endpoint, label: endpoint.endpoint,
title: endpoint.endpoint, title: endpoint.endpoint,
url: endpoint.endpoint, CSSStyles: { ...cssStyles.hyperlink } url: endpoint.endpoint
}) })
.component(); .component();
} }
@@ -468,7 +468,7 @@ function createEndpointComponent(modelBuilder: azdata.ModelBuilder, endpoint: En
title: endpoint.endpoint, title: endpoint.endpoint,
label: endpoint.endpoint, label: endpoint.endpoint,
url: '', url: '',
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } CSSStyles: { ...cssStyles.text }
}).component(); }).component();
endpointCell.onDidClick(async () => { endpointCell.onDidClick(async () => {
const connProfile = bdcModel.getSqlServerMasterConnectionProfile(); const connProfile = bdcModel.getSqlServerMasterConnectionProfile();

View File

@@ -304,7 +304,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
url: instanceStatus.dashboards.nodeMetricsUrl, url: instanceStatus.dashboards.nodeMetricsUrl,
title: instanceStatus.dashboards.nodeMetricsUrl, title: instanceStatus.dashboards.nodeMetricsUrl,
ariaLabel: loc.viewNodeMetrics(instanceStatus.dashboards.nodeMetricsUrl), ariaLabel: loc.viewNodeMetrics(instanceStatus.dashboards.nodeMetricsUrl),
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } CSSStyles: { ...cssStyles.text }
}).component()); }).component());
} }
@@ -319,7 +319,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
url: instanceStatus.dashboards.sqlMetricsUrl, url: instanceStatus.dashboards.sqlMetricsUrl,
title: instanceStatus.dashboards.sqlMetricsUrl, title: instanceStatus.dashboards.sqlMetricsUrl,
ariaLabel: loc.viewSqlMetrics(instanceStatus.dashboards.sqlMetricsUrl), ariaLabel: loc.viewSqlMetrics(instanceStatus.dashboards.sqlMetricsUrl),
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } CSSStyles: { ...cssStyles.text }
}).component()); }).component());
} }
} }
@@ -332,7 +332,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
url: instanceStatus.dashboards.logsUrl, url: instanceStatus.dashboards.logsUrl,
title: instanceStatus.dashboards.logsUrl, title: instanceStatus.dashboards.logsUrl,
ariaLabel: loc.viewLogs(instanceStatus.dashboards.logsUrl), ariaLabel: loc.viewLogs(instanceStatus.dashboards.logsUrl),
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } CSSStyles: { ...cssStyles.text }
}).component()); }).component());
} }
return row; return row;

View File

@@ -16,20 +16,15 @@
padding-left: 20px; padding-left: 20px;
} }
.slick-cell a, a:link { .slick-cell a,
color: var(--color-grid-link); .slick-cell a:link,
text-decoration: underline; .resultsMessageValue a,
} .resultsMessageValue a:link {
.slick-cell a:hover {
color: var(--color-grid-link-hover);
}
.resultsMessageValue a, a:link {
color: var(--color-grid-link); color: var(--color-grid-link);
text-decoration: underline; text-decoration: underline;
} }
.slick-cell a:hover,
.resultsMessageValue a:hover { .resultsMessageValue a:hover {
color: var(--color-grid-link-hover); color: var(--color-grid-link-hover);
} }

View File

@@ -12,10 +12,14 @@ import * as azdata from 'azdata';
import { TitledComponent } from 'sql/workbench/browser/modelComponents/titledComponent'; import { TitledComponent } from 'sql/workbench/browser/modelComponents/titledComponent';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces'; import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces';
import { registerThemingParticipant, IColorTheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { textLinkForeground, textLinkActiveForeground } from 'vs/platform/theme/common/colorRegistry';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import * as DOM from 'vs/base/browser/dom';
@Component({ @Component({
selector: 'modelview-hyperlink', selector: 'modelview-hyperlink',
template: `<a [href]="getUrl()" [title]="title" [attr.aria-label]="ariaLabel" target="blank" (click)="onClick()">{{getLabel()}}</a>` template: `<a [href]="url" [title]="title" [attr.aria-label]="ariaLabel" target="blank">{{label}}</a>`
}) })
export default class HyperlinkComponent extends TitledComponent implements IComponent, OnDestroy, AfterViewInit { export default class HyperlinkComponent extends TitledComponent implements IComponent, OnDestroy, AfterViewInit {
@Input() descriptor: IComponentDescriptor; @Input() descriptor: IComponentDescriptor;
@@ -23,7 +27,9 @@ export default class HyperlinkComponent extends TitledComponent implements IComp
constructor( constructor(
@Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef, @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef,
@Inject(forwardRef(() => ElementRef)) el: ElementRef) { @Inject(forwardRef(() => ElementRef)) el: ElementRef,
@Inject(IOpenerService) private openerService: IOpenerService
) {
super(changeRef, el); super(changeRef, el);
} }
@@ -32,6 +38,7 @@ export default class HyperlinkComponent extends TitledComponent implements IComp
} }
ngAfterViewInit(): void { ngAfterViewInit(): void {
this._register(DOM.addDisposableListener(this._el.nativeElement, 'click', (e: MouseEvent) => this.onClick(e)));
} }
ngOnDestroy(): void { ngOnDestroy(): void {
@@ -50,10 +57,6 @@ export default class HyperlinkComponent extends TitledComponent implements IComp
return this.getPropertyOrDefault<azdata.HyperlinkComponentProperties, string>((props) => props.label, ''); return this.getPropertyOrDefault<azdata.HyperlinkComponentProperties, string>((props) => props.label, '');
} }
public getLabel(): string {
return this.label;
}
public set url(newValue: string) { public set url(newValue: string) {
this.setPropertyFromUI<azdata.HyperlinkComponentProperties, string>((properties, value) => { properties.url = value; }, newValue); this.setPropertyFromUI<azdata.HyperlinkComponentProperties, string>((properties, value) => { properties.url = value; }, newValue);
} }
@@ -62,17 +65,35 @@ export default class HyperlinkComponent extends TitledComponent implements IComp
return this.getPropertyOrDefault<azdata.HyperlinkComponentProperties, string>((props) => props.url, ''); return this.getPropertyOrDefault<azdata.HyperlinkComponentProperties, string>((props) => props.url, '');
} }
public getUrl(): string { public onClick(e: MouseEvent): void {
return this.url;
}
public onClick(): boolean {
this.fireEvent({ this.fireEvent({
eventType: ComponentEventType.onDidClick, eventType: ComponentEventType.onDidClick,
args: undefined args: undefined
}); });
// If we don't have a URL then return false since that just defaults to the URL for the workbench. We assume if (this.url) {
// if a blank url is specified then the caller is handling the click themselves. this.openerService.open(this.url);
return !!this.url; }
DOM.EventHelper.stop(e, true);
} }
} }
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
const linkForeground = theme.getColor(textLinkForeground);
if (linkForeground) {
collector.addRule(`
modelview-hyperlink a:link,
modelview-hyperlink a:visited {
color: ${linkForeground};
}
`);
}
const activeForeground = theme.getColor(textLinkActiveForeground);
if (activeForeground) {
collector.addRule(`
modelview-hyperlink a:hover {
color: ${activeForeground};
}
`);
}
});