diff --git a/extensions/big-data-cluster/src/bigDataCluster/constants.ts b/extensions/big-data-cluster/src/bigDataCluster/constants.ts index 139e682d7c..dfe2569e2c 100644 --- a/extensions/big-data-cluster/src/bigDataCluster/constants.ts +++ b/extensions/big-data-cluster/src/bigDataCluster/constants.ts @@ -59,7 +59,6 @@ export class IconPathHelper { export namespace cssStyles { 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 hyperlink = { 'user-select': 'text', 'color': '#0078d4', 'text-decoration': 'underline', 'cursor': 'pointer' }; export const text = { 'margin-block-start': '0px', 'margin-block-end': '0px' }; export const overflowEllipsisText = { ...text, 'overflow': 'hidden', 'text-overflow': 'ellipsis' }; export const nonSelectableText = { ...cssStyles.text, 'user-select': 'none' }; diff --git a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts index 42c4b2241c..6fdfe2d95e 100644 --- a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts +++ b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardOverviewPage.ts @@ -363,7 +363,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage { .withProperties({ label: getServiceNameDisplayText(serviceStatus.serviceName), url: '', - CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } + CSSStyles: { ...cssStyles.text } }).component(); nameCell.onDidClick(() => { this.dashboard.switchToServiceTab(serviceStatus.serviceName); @@ -458,7 +458,7 @@ function createEndpointComponent(modelBuilder: azdata.ModelBuilder, endpoint: En .withProperties({ label: endpoint.endpoint, title: endpoint.endpoint, - url: endpoint.endpoint, CSSStyles: { ...cssStyles.hyperlink } + url: endpoint.endpoint }) .component(); } @@ -468,7 +468,7 @@ function createEndpointComponent(modelBuilder: azdata.ModelBuilder, endpoint: En title: endpoint.endpoint, label: endpoint.endpoint, url: '', - CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } + CSSStyles: { ...cssStyles.text } }).component(); endpointCell.onDidClick(async () => { const connProfile = bdcModel.getSqlServerMasterConnectionProfile(); diff --git a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardResourceStatusPage.ts b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardResourceStatusPage.ts index d769bb9ed6..736f735f3e 100644 --- a/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardResourceStatusPage.ts +++ b/extensions/big-data-cluster/src/bigDataCluster/dialog/bdcDashboardResourceStatusPage.ts @@ -304,7 +304,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage { url: instanceStatus.dashboards.nodeMetricsUrl, title: instanceStatus.dashboards.nodeMetricsUrl, ariaLabel: loc.viewNodeMetrics(instanceStatus.dashboards.nodeMetricsUrl), - CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } + CSSStyles: { ...cssStyles.text } }).component()); } @@ -319,7 +319,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage { url: instanceStatus.dashboards.sqlMetricsUrl, title: instanceStatus.dashboards.sqlMetricsUrl, ariaLabel: loc.viewSqlMetrics(instanceStatus.dashboards.sqlMetricsUrl), - CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } + CSSStyles: { ...cssStyles.text } }).component()); } } @@ -332,7 +332,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage { url: instanceStatus.dashboards.logsUrl, title: instanceStatus.dashboards.logsUrl, ariaLabel: loc.viewLogs(instanceStatus.dashboards.logsUrl), - CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink } + CSSStyles: { ...cssStyles.text } }).component()); } return row; diff --git a/src/sql/base/browser/ui/table/media/slickColorTheme.css b/src/sql/base/browser/ui/table/media/slickColorTheme.css index 0387ba62ce..e64c3be82f 100644 --- a/src/sql/base/browser/ui/table/media/slickColorTheme.css +++ b/src/sql/base/browser/ui/table/media/slickColorTheme.css @@ -16,20 +16,15 @@ padding-left: 20px; } -.slick-cell a, a:link { - color: var(--color-grid-link); - text-decoration: underline; -} - -.slick-cell a:hover { - color: var(--color-grid-link-hover); -} - -.resultsMessageValue a, a:link { +.slick-cell a, +.slick-cell a:link, +.resultsMessageValue a, +.resultsMessageValue a:link { color: var(--color-grid-link); text-decoration: underline; } +.slick-cell a:hover, .resultsMessageValue a:hover { color: var(--color-grid-link-hover); } diff --git a/src/sql/workbench/browser/modelComponents/hyperlink.component.ts b/src/sql/workbench/browser/modelComponents/hyperlink.component.ts index 8eb19a64e1..62ca3b1d72 100644 --- a/src/sql/workbench/browser/modelComponents/hyperlink.component.ts +++ b/src/sql/workbench/browser/modelComponents/hyperlink.component.ts @@ -12,10 +12,14 @@ import * as azdata from 'azdata'; import { TitledComponent } from 'sql/workbench/browser/modelComponents/titledComponent'; 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({ selector: 'modelview-hyperlink', - template: `{{getLabel()}}` + template: `{{label}}` }) export default class HyperlinkComponent extends TitledComponent implements IComponent, OnDestroy, AfterViewInit { @Input() descriptor: IComponentDescriptor; @@ -23,7 +27,9 @@ export default class HyperlinkComponent extends TitledComponent implements IComp constructor( @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef, - @Inject(forwardRef(() => ElementRef)) el: ElementRef) { + @Inject(forwardRef(() => ElementRef)) el: ElementRef, + @Inject(IOpenerService) private openerService: IOpenerService + ) { super(changeRef, el); } @@ -32,6 +38,7 @@ export default class HyperlinkComponent extends TitledComponent implements IComp } ngAfterViewInit(): void { + this._register(DOM.addDisposableListener(this._el.nativeElement, 'click', (e: MouseEvent) => this.onClick(e))); } ngOnDestroy(): void { @@ -50,10 +57,6 @@ export default class HyperlinkComponent extends TitledComponent implements IComp return this.getPropertyOrDefault((props) => props.label, ''); } - public getLabel(): string { - return this.label; - } - public set url(newValue: string) { this.setPropertyFromUI((properties, value) => { properties.url = value; }, newValue); } @@ -62,17 +65,35 @@ export default class HyperlinkComponent extends TitledComponent implements IComp return this.getPropertyOrDefault((props) => props.url, ''); } - public getUrl(): string { - return this.url; - } - - public onClick(): boolean { + public onClick(e: MouseEvent): void { this.fireEvent({ eventType: ComponentEventType.onDidClick, 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 a blank url is specified then the caller is handling the click themselves. - return !!this.url; + if (this.url) { + this.openerService.open(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}; + } + `); + } +});