Add aria labels and consolidate loc strings (#8494)

This commit is contained in:
Charles Gagnon
2019-12-02 13:33:24 -08:00
committed by GitHub
parent 9a83dfc022
commit b8bc629970
11 changed files with 207 additions and 148 deletions

View File

@@ -5,24 +5,19 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { ClusterController, ControllerError } from '../controller/clusterControllerApi';
import { ControllerTreeDataProvider } from '../tree/controllerTreeDataProvider';
import { AuthType } from '../constants';
import { BdcDashboardOptions } from './bdcDashboardModel';
import { ControllerNode } from '../tree/controllerTreeNode';
import { ManageControllerCommand } from '../../commands';
const localize = nls.loadMessageBundle();
const basicAuthDisplay = localize('basicAuthName', "Basic");
const integratedAuthDisplay = localize('integratedAuthName', "Windows Authentication");
import * as loc from '../localizedConstants';
function getAuthCategory(name: AuthType): azdata.CategoryValue {
if (name === 'basic') {
return { name: name, displayName: basicAuthDisplay };
return { name: name, displayName: loc.basic };
}
return { name: name, displayName: integratedAuthDisplay };
return { name: name, displayName: loc.windowsAuth };
}
export class AddControllerDialogModel {
@@ -62,9 +57,9 @@ export class AddControllerDialogModel {
if (auth === 'basic') {
// Verify username and password as we can't make them required in the UI
if (!username) {
throw new Error(localize('err.controller.username.required', "Username is required"));
throw new Error(loc.usernameRequired);
} else if (!password) {
throw new Error(localize('err.controller.password.required', "Password is required"));
throw new Error(loc.passwordRequired);
}
}
// We pre-fetch the endpoints here to verify that the information entered is correct (the user is able to connect)
@@ -119,13 +114,13 @@ export class AddControllerDialog {
}
private createDialog(): void {
this.dialog = azdata.window.createModelViewDialog(localize('textAddNewController', "Add New Controller (preview)"));
this.dialog = azdata.window.createModelViewDialog(loc.addNewController);
this.dialog.registerContent(async view => {
this.uiModelBuilder = view.modelBuilder;
this.urlInputBox = this.uiModelBuilder.inputBox()
.withProperties<azdata.InputBoxProperties>({
placeHolder: localize('textUrlLower', "url"),
placeHolder: loc.url.toLocaleLowerCase(),
value: this.model.prefilledUrl
}).component();
this.authDropdown = this.uiModelBuilder.dropDown().withProperties({
@@ -136,19 +131,19 @@ export class AddControllerDialog {
this.authDropdown.onValueChanged(e => this.onAuthChanged());
this.usernameInputBox = this.uiModelBuilder.inputBox()
.withProperties<azdata.InputBoxProperties>({
placeHolder: localize('textUsernameLower', "username"),
placeHolder: loc.usernameRequired.toLocaleLowerCase(),
value: this.model.prefilledUsername
}).component();
this.passwordInputBox = this.uiModelBuilder.inputBox()
.withProperties<azdata.InputBoxProperties>({
placeHolder: localize('textPasswordLower', "password"),
placeHolder: loc.password,
inputType: 'password',
value: this.model.prefilledPassword
})
.component();
this.rememberPwCheckBox = this.uiModelBuilder.checkBox()
.withProperties<azdata.CheckBoxProperties>({
label: localize('textRememberPassword', "Remember Password"),
label: loc.rememberPassword,
checked: this.model.prefilledRememberPassword
}).component();
@@ -157,19 +152,19 @@ export class AddControllerDialog {
components: [
{
component: this.urlInputBox,
title: localize('textUrlCapital', "Cluster Management URL"),
title: loc.clusterUrl,
required: true
}, {
component: this.authDropdown,
title: localize('textAuthCapital', "Authentication type"),
title: loc.authType,
required: true
}, {
component: this.usernameInputBox,
title: localize('textUsernameCapital', "Username"),
title: loc.username,
required: false
}, {
component: this.passwordInputBox,
title: localize('textPasswordCapital', "Password"),
title: loc.password,
required: false
}, {
component: this.rememberPwCheckBox,
@@ -185,8 +180,8 @@ export class AddControllerDialog {
this.dialog.registerCloseValidator(async () => await this.validate());
this.dialog.cancelButton.onClick(async () => await this.cancel());
this.dialog.okButton.label = localize('textAdd', "Add");
this.dialog.cancelButton.label = localize('textCancel', "Cancel");
this.dialog.okButton.label = loc.add;
this.dialog.cancelButton.label = loc.cancel;
}
private get authValue(): AuthType {

View File

@@ -5,7 +5,6 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { BdcDashboardModel, getTroubleshootNotebookUrl, BdcErrorEvent } from './bdcDashboardModel';
import { IconPathHelper, cssStyles } from '../constants';
import { BdcServiceStatusPage } from './bdcServiceStatusPage';
@@ -14,8 +13,7 @@ import { BdcStatusModel, ServiceStatusModel } from '../controller/apiGenerated';
import { getHealthStatusDot, getServiceNameDisplayText, showErrorMessage } from '../utils';
import { HdfsDialogCancelledError } from './hdfsDialogBase';
import { BdcDashboardPage } from './bdcDashboardPage';
const localize = nls.loadMessageBundle();
import * as loc from '../localizedConstants';
const navWidth = '200px';
@@ -69,7 +67,7 @@ export class BdcDashboard extends BdcDashboardPage {
// Refresh button
this.refreshButton = modelView.modelBuilder.button()
.withProperties<azdata.ButtonProperties>({
label: localize('bdc.dashboard.refreshButton', "Refresh"),
label: loc.refresh,
iconPath: IconPathHelper.refresh
}).component();
@@ -80,7 +78,7 @@ export class BdcDashboard extends BdcDashboardPage {
const openTroubleshootNotebookButton = modelView.modelBuilder.button()
.withProperties<azdata.ButtonProperties>({
label: localize('bdc.dashboard.troubleshootButton', "Troubleshoot"),
label: loc.troubleshoot,
iconPath: IconPathHelper.notebook
}).component();
@@ -136,7 +134,7 @@ export class BdcDashboard extends BdcDashboardPage {
ariaRole: 'tab',
ariaSelected: true
}).component();
const overviewNavItemText = modelView.modelBuilder.text().withProperties({ value: localize('bdc.dashboard.overviewNavTitle', "Big Data Cluster overview") }).component();
const overviewNavItemText = modelView.modelBuilder.text().withProperties({ value: loc.bdcOverview }).component();
overviewNavItemText.updateCssStyles(selectedTabCss);
overviewNavItemDiv.addItem(overviewNavItemText, { CSSStyles: { 'user-select': 'text' } });
this.overviewPage = new BdcDashboardOverviewPage(this, this.model);
@@ -159,7 +157,7 @@ export class BdcDashboard extends BdcDashboardPage {
});
this.navContainer.addItem(overviewNavItemDiv, { flex: '0 0 auto' });
const clusterDetailsHeader = modelView.modelBuilder.text().withProperties({ value: localize('bdc.dashboard.clusterDetails', "Cluster Details"), CSSStyles: { 'margin-block-end': '0px' } }).component();
const clusterDetailsHeader = modelView.modelBuilder.text().withProperties({ value: loc.clusterDetails, CSSStyles: { 'margin-block-end': '0px' } }).component();
this.navContainer.addItem(clusterDetailsHeader, { CSSStyles: { 'user-select': 'none', 'font-weight': 'bold', 'border-bottom': 'solid 1px #ccc', 'margin-bottom': '10px' } });
await modelView.initializeModel(rootContainer);

View File

@@ -5,7 +5,6 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { BdcDashboardModel, BdcErrorEvent } from './bdcDashboardModel';
import { IconPathHelper, cssStyles } from '../constants';
import { getStateDisplayText, getHealthStatusDisplayText, getEndpointDisplayText, getHealthStatusIcon, getServiceNameDisplayText, Endpoint, getBdcStatusErrorMessage } from '../utils';
@@ -14,8 +13,7 @@ import { BdcDashboard } from './bdcDashboard';
import { createViewDetailsButton } from './commonControls';
import { HdfsDialogCancelledError } from './hdfsDialogBase';
import { BdcDashboardPage } from './bdcDashboardPage';
const localize = nls.loadMessageBundle();
import * as loc from '../localizedConstants';
const clusterStateLabelColumnWidth = 100;
const clusterStateValueColumnWidth = 225;
@@ -63,7 +61,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
// ##############
const propertiesLabel = view.modelBuilder.text()
.withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.propertiesHeader', "Cluster Properties"), CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '10px' } })
.withProperties<azdata.TextComponentProperties>({ value: loc.clusterProperties, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '10px' } })
.component();
rootContainer.addItem(propertiesLabel, { CSSStyles: { 'margin-top': '15px', 'padding-left': '10px', ...cssStyles.title } });
@@ -76,14 +74,14 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
const row1 = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', height: '30px', alignItems: 'center' }).component();
// Cluster State
const clusterStateLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.clusterState', "Cluster State :") }).component();
const clusterStateLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.clusterState }).component();
const clusterStateValue = view.modelBuilder.text().component();
this.clusterStateLoadingComponent = view.modelBuilder.loadingComponent().withItem(clusterStateValue).component();
row1.addItem(clusterStateLabel, { CSSStyles: { 'width': `${clusterStateLabelColumnWidth}px`, 'min-width': `${clusterStateLabelColumnWidth}px`, 'user-select': 'none', 'font-weight': 'bold' } });
row1.addItem(this.clusterStateLoadingComponent, { CSSStyles: { 'width': `${clusterStateValueColumnWidth}px`, 'min-width': `${clusterStateValueColumnWidth}px` } });
// Health Status
const healthStatusLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.healthStatus', "Health Status :") }).component();
const healthStatusLabel = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.healthStatusWithColon }).component();
const healthStatusValue = view.modelBuilder.text().component();
this.clusterHealthStatusLoadingComponent = view.modelBuilder.loadingComponent().withItem(healthStatusValue).component();
row1.addItem(healthStatusLabel, { CSSStyles: { 'width': `${healthStatusColumnWidth}px`, 'min-width': `${healthStatusColumnWidth}px`, 'user-select': 'none', 'font-weight': 'bold' } });
@@ -102,7 +100,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
const overviewLabel = view.modelBuilder.text()
.withProperties<azdata.TextComponentProperties>({
value: localize('bdc.dashboard.overviewHeader', "Cluster Overview"),
value: loc.clusterOverview,
CSSStyles: { ...cssStyles.text }
})
.component();
@@ -111,7 +109,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
this.lastUpdatedLabel = view.modelBuilder.text()
.withProperties({
value: localize('bdc.dashboard.lastUpdated', "Last Updated : {0}", '-'),
value: loc.lastUpdated(),
CSSStyles: { ...cssStyles.lastUpdatedText }
}).component();
@@ -125,6 +123,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
columns: [
{ // status icon
displayName: '',
ariaLabel: loc.statusIcon,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 25,
@@ -140,7 +139,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
},
},
{ // service
displayName: localize('bdc.dashboard.serviceNameHeader', "Service Name"),
displayName: loc.serviceName,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 175,
@@ -157,7 +156,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
},
},
{ // state
displayName: localize('bdc.dashboard.stateHeader', "State"),
displayName: loc.state,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: 150,
@@ -174,7 +173,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
},
},
{ // health status
displayName: localize('bdc.dashboard.healthStatusHeader', "Health Status"),
displayName: loc.healthStatus,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: 100,
@@ -193,6 +192,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
},
{ // view details button
displayName: '',
ariaLabel: loc.viewDetails,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 150,
@@ -208,7 +208,8 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
},
},
],
data: []
data: [],
ariaLabel: loc.clusterOverview
})
.component();
@@ -236,7 +237,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
// #####################
const endpointsLabel = view.modelBuilder.text()
.withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.endpointsLabel', "Service Endpoints"), CSSStyles: { 'margin-block-start': '20px', 'margin-block-end': '0px' } })
.withProperties<azdata.TextComponentProperties>({ value: loc.serviceEndpoints, CSSStyles: { 'margin-block-start': '20px', 'margin-block-end': '0px' } })
.component();
rootContainer.addItem(endpointsLabel, { CSSStyles: { 'padding-left': '10px', ...cssStyles.title } });
@@ -249,7 +250,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
{
columns: [
{ // service
displayName: localize('bdc.dashboard.serviceHeader', "Service"),
displayName: loc.service,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: 200,
@@ -266,7 +267,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
},
},
{ // endpoint
displayName: localize('bdc.dashboard.endpointHeader', "Endpoint"),
displayName: loc.endpoint,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 350,
@@ -286,6 +287,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
},
{ // copy
displayName: '',
ariaLabel: loc.copy,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 50,
@@ -301,7 +303,8 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
}
}
],
data: []
data: [],
ariaLabel: loc.serviceEndpoints
}).component();
this.endpointsDisplayContainer = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
@@ -342,11 +345,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
if (!bdcStatus) {
return;
}
this.lastUpdatedLabel.value =
localize('bdc.dashboard.lastUpdated', "Last Updated : {0}",
this.model.bdcStatusLastUpdated ?
`${this.model.bdcStatusLastUpdated.toLocaleDateString()} ${this.model.bdcStatusLastUpdated.toLocaleTimeString()}`
: '-');
this.lastUpdatedLabel.value = loc.lastUpdated(this.model.bdcStatusLastUpdated);
this.clusterStateLoadingComponent.loading = false;
this.clusterHealthStatusLoadingComponent.loading = false;
@@ -400,11 +399,11 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
endpoints.unshift(...sqlServerMasterEndpoints);
this.endpointsTable.data = endpoints.map(e => {
const copyValueCell = this.modelBuilder.button().withProperties<azdata.ButtonProperties>({ title: localize('bdc.dashboard.copyTitle', "Copy") }).component();
const copyValueCell = this.modelBuilder.button().withProperties<azdata.ButtonProperties>({ title: loc.copy }).component();
copyValueCell.iconPath = IconPathHelper.copy;
copyValueCell.onDidClick(() => {
vscode.env.clipboard.writeText(e.endpoint);
vscode.window.showInformationMessage(localize('copiedEndpoint', "Endpoint '{0}' copied to clipboard", getEndpointDisplayText(e.name, e.description)));
vscode.window.showInformationMessage(loc.copiedEndpoint(getEndpointDisplayText(e.name, e.description)));
});
copyValueCell.iconHeight = '14px';
copyValueCell.iconWidth = '14px';
@@ -418,7 +417,7 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
private handleBdcError(errorEvent: BdcErrorEvent): void {
if (errorEvent.errorType === 'bdcEndpoints') {
const errorMessage = localize('endpointsError', "Unexpected error retrieving BDC Endpoints: {0}", errorEvent.error.message);
const errorMessage = loc.endpointsError(errorEvent.error.message);
this.showEndpointsError(errorMessage);
} else if (errorEvent.errorType === 'bdcStatus') {
this.showBdcStatusError(getBdcStatusErrorMessage(errorEvent.error));
@@ -444,11 +443,11 @@ export class BdcDashboardOverviewPage extends BdcDashboardPage {
private handleGeneralError(error: Error): void {
if (error instanceof HdfsDialogCancelledError) {
const errorMessage = localize('bdc.dashboard.noConnection', "The dashboard requires a connection. Please click retry to enter your credentials.");
const errorMessage = loc.noConnectionError;
this.showBdcStatusError(errorMessage);
this.showEndpointsError(errorMessage);
} else {
const errorMessage = localize('bdc.dashboard.unexpectedError', "Unexpected error occurred: {0}", error.message);
const errorMessage = loc.unexpectedError(error);
this.showBdcStatusError(errorMessage);
this.showEndpointsError(errorMessage);
}

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as nls from 'vscode-nls';
import { BdcDashboardModel } from './bdcDashboardModel';
import { BdcStatusModel, InstanceStatusModel, ResourceStatusModel } from '../controller/apiGenerated';
import { getHealthStatusDisplayText, getHealthStatusIcon, getStateDisplayText, Service } from '../utils';
@@ -12,11 +11,7 @@ import { cssStyles } from '../constants';
import { isNullOrUndefined } from 'util';
import { createViewDetailsButton } from './commonControls';
import { BdcDashboardPage } from './bdcDashboardPage';
const localize = nls.loadMessageBundle();
const viewText = localize('bdc.dashboard.viewHyperlink', "View");
const notAvailableText = localize('bdc.dashboard.notAvailable', "N/A");
import * as loc from '../localizedConstants';
export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
@@ -60,7 +55,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
// Header label
const healthStatusHeaderLabel = this.modelView.modelBuilder.text()
.withProperties<azdata.TextComponentProperties>({
value: localize('bdc.dashboard.healthStatusDetailsHeader', "Health Status Details"),
value: loc.healthStatusDetails,
CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '10px' }
})
.component();
@@ -70,7 +65,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
// Last updated label
this.lastUpdatedLabel = this.modelView.modelBuilder.text()
.withProperties({
value: this.getLastUpdatedText(),
value: loc.lastUpdated(this.model.bdcStatusLastUpdated),
CSSStyles: { ...cssStyles.lastUpdatedText }
}).component();
@@ -82,6 +77,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
columns: [
{ // status icon
displayName: '',
ariaLabel: loc.statusIcon,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 25,
@@ -97,7 +93,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
},
},
{ // instance
displayName: localize('bdc.dashboard.instanceHeader', "Instance"),
displayName: loc.instance,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: 100,
@@ -114,7 +110,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
},
},
{ // state
displayName: localize('bdc.dashboard.stateHeader', "State"),
displayName: loc.state,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: 150,
@@ -131,7 +127,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
},
},
{ // health status
displayName: localize('bdc.dashboard.healthStatusHeader', "Health Status"),
displayName: loc.healthStatus,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: 100,
@@ -150,6 +146,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
},
{ // view details button
displayName: '',
ariaLabel: loc.viewDetails,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 150,
@@ -165,7 +162,8 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
},
},
],
data: this.createHealthStatusRows()
data: this.createHealthStatusRows(),
ariaLabel: loc.healthStatusDetails
}).component();
this.rootContainer.addItem(this.instanceHealthStatusTable, { flex: '0 0 auto' });
@@ -175,14 +173,14 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
// Title label
const endpointsLabel = this.modelView.modelBuilder.text()
.withProperties<azdata.TextComponentProperties>({ value: localize('bdc.dashboard.metricsAndLogsLabel', "Metrics and Logs"), CSSStyles: { 'margin-block-start': '20px', 'margin-block-end': '0px' } })
.withProperties<azdata.TextComponentProperties>({ value: loc.metricsAndLogs, CSSStyles: { 'margin-block-start': '20px', 'margin-block-end': '0px' } })
.component();
this.rootContainer.addItem(endpointsLabel, { CSSStyles: { 'padding-left': '10px', ...cssStyles.title } });
let metricsAndLogsColumns: azdata.DeclarativeTableColumn[] =
[
{ // instance
displayName: localize('bdc.dashboard.instanceHeader', "Instance"),
displayName: loc.instance,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: 125,
@@ -199,7 +197,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
},
},
{ // node metrics
displayName: localize('bdc.dashboard.nodeMetricsHeader', "Node Metrics"),
displayName: loc.nodeMetrics,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 100,
@@ -221,7 +219,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
if (this.serviceName.toLowerCase() === Service.sql) {
metricsAndLogsColumns.push(
{ // sql metrics
displayName: localize('bdc.dashboard.sqlMetricsHeader', "SQL Metrics"),
displayName: loc.sqlMetrics,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 100,
@@ -242,7 +240,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
metricsAndLogsColumns.push(
{ // logs
displayName: localize('bdc.dashboard.logsHeader', "Logs"),
displayName: loc.logs,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: 100,
@@ -264,10 +262,10 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
.withProperties<azdata.DeclarativeTableProperties>(
{
columns: metricsAndLogsColumns,
data: this.createMetricsAndLogsRows()
data: this.createMetricsAndLogsRows(),
ariaLabel: loc.metricsAndLogs
}).component();
this.rootContainer.addItem(this.metricsAndLogsRowsTable, { flex: '0 0 auto' });
this.initialized = true;
}
@@ -288,7 +286,7 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
return;
}
this.lastUpdatedLabel.value = this.getLastUpdatedText();
this.lastUpdatedLabel.value = loc.lastUpdated(this.model.bdcStatusLastUpdated);
this.instanceHealthStatusTable.data = this.createHealthStatusRows();
@@ -308,10 +306,10 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
// Not all instances have all logs available - in that case just display N/A instead of a link
if (isNullOrUndefined(instanceStatus.dashboards) || isNullOrUndefined(instanceStatus.dashboards.nodeMetricsUrl)) {
row.push(this.modelView.modelBuilder.text().withProperties({ value: notAvailableText, CSSStyles: { ...cssStyles.text } }).component());
row.push(this.modelView.modelBuilder.text().withProperties({ value: loc.notAvailable, CSSStyles: { ...cssStyles.text } }).component());
} else {
row.push(this.modelView.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({
label: viewText,
label: loc.view,
url: instanceStatus.dashboards.nodeMetricsUrl,
title: instanceStatus.dashboards.nodeMetricsUrl,
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink }
@@ -322,10 +320,10 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
if (this.serviceName === Service.sql) {
// Not all instances have all logs available - in that case just display N/A instead of a link
if (isNullOrUndefined(instanceStatus.dashboards) || isNullOrUndefined(instanceStatus.dashboards.sqlMetricsUrl)) {
row.push(this.modelView.modelBuilder.text().withProperties({ value: notAvailableText, CSSStyles: { ...cssStyles.text } }).component());
row.push(this.modelView.modelBuilder.text().withProperties({ value: loc.notAvailable, CSSStyles: { ...cssStyles.text } }).component());
} else {
row.push(this.modelView.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({
label: viewText,
label: loc.view,
url: instanceStatus.dashboards.sqlMetricsUrl,
title: instanceStatus.dashboards.sqlMetricsUrl,
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink }
@@ -334,10 +332,10 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
}
if (isNullOrUndefined(instanceStatus.dashboards) || isNullOrUndefined(instanceStatus.dashboards.logsUrl)) {
row.push(this.modelView.modelBuilder.text().withProperties({ value: notAvailableText, CSSStyles: { ...cssStyles.text } }).component());
row.push(this.modelView.modelBuilder.text().withProperties({ value: loc.notAvailable, CSSStyles: { ...cssStyles.text } }).component());
} else {
row.push(this.modelView.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({
label: viewText,
label: loc.view,
url: instanceStatus.dashboards.logsUrl,
title: instanceStatus.dashboards.logsUrl,
CSSStyles: { ...cssStyles.text, ...cssStyles.hyperlink }
@@ -363,11 +361,4 @@ export class BdcDashboardResourceStatusPage extends BdcDashboardPage {
getHealthStatusDisplayText(instanceStatus.healthStatus),
viewDetailsButton];
}
private getLastUpdatedText(): string {
return localize('bdc.dashboard.lastUpdated', "Last Updated : {0}",
this.model.bdcStatusLastUpdated ?
`${this.model.bdcStatusLastUpdated.toLocaleDateString()} ${this.model.bdcStatusLastUpdated.toLocaleTimeString()}`
: '-');
}
}

View File

@@ -5,12 +5,10 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import * as loc from '../localizedConstants';
export function createViewDetailsButton(modelBuilder: azdata.ModelBuilder, text: string): azdata.ButtonComponent {
const viewDetailsButton = modelBuilder.button().withProperties<azdata.ButtonProperties>({ label: localize('bdc.dashboard.viewDetails', "View Details") }).component();
const viewDetailsButton = modelBuilder.button().withProperties<azdata.ButtonProperties>({ label: loc.viewDetails }).component();
viewDetailsButton.onDidClick(() => {
vscode.window.showErrorMessage(text, { modal: true });
});

View File

@@ -4,15 +4,14 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as nls from 'vscode-nls';
import { HdfsDialogBase, HdfsDialogModelBase, HdfsDialogProperties } from './hdfsDialogBase';
import { ClusterController } from '../controller/clusterControllerApi';
import * as loc from '../localizedConstants';
const localize = nls.loadMessageBundle();
export class ConnectControllerDialog extends HdfsDialogBase<HdfsDialogProperties, ClusterController> {
constructor(model: ConnectControllerModel) {
super(localize('connectController.dialog.title', "Connect to Controller (preview)"), model);
super(loc.connectToController, model);
}
protected getMainSectionComponents(): (azdata.FormComponentGroup | azdata.FormComponent)[] {

View File

@@ -4,21 +4,16 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as nls from 'vscode-nls';
import { ClusterController, ControllerError, IEndPointsResponse } from '../controller/clusterControllerApi';
import { AuthType } from '../constants';
import { Deferred } from '../../common/promise';
const localize = nls.loadMessageBundle();
const basicAuthDisplay = localize('basicAuthName', "Basic");
const integratedAuthDisplay = localize('integratedAuthName', "Windows Authentication");
import * as loc from '../localizedConstants';
function getAuthCategory(name: AuthType): azdata.CategoryValue {
if (name === 'basic') {
return { name: name, displayName: basicAuthDisplay };
return { name: name, displayName: loc.basic };
}
return { name: name, displayName: integratedAuthDisplay };
return { name: name, displayName: loc.windowsAuth };
}
export interface HdfsDialogProperties {
@@ -90,10 +85,10 @@ export abstract class HdfsDialogModelBase<T extends HdfsDialogProperties, R> {
try {
response = await controller.getEndPoints();
if (!response || !response.endPoints) {
throw new Error(localize('mount.hdfs.loginerror1', "Login to controller failed"));
throw new Error(loc.loginFailed);
}
} catch (err) {
throw new Error(localize('mount.hdfs.loginerror2', "Login to controller failed: {0}", err.statusMessage || err.message));
throw new Error(loc.loginFailedWithError(err));
}
return controller;
}
@@ -102,9 +97,9 @@ export abstract class HdfsDialogModelBase<T extends HdfsDialogProperties, R> {
if (this.props.auth === 'basic') {
// Verify username and password as we can't make them required in the UI
if (!this.props.username) {
throw new Error(localize('err.controller.username.required', "Username is required"));
throw new Error(loc.usernameRequired);
} else if (!this.props.password) {
throw new Error(localize('err.controller.password.required', "Password is required"));
throw new Error(loc.passwordRequired);
}
}
}
@@ -139,7 +134,7 @@ export abstract class HdfsDialogBase<T extends HdfsDialogProperties, R> {
this.urlInputBox = this.uiModelBuilder.inputBox()
.withProperties<azdata.InputBoxProperties>({
placeHolder: localize('textUrlLower', "url"),
placeHolder: loc.url.toLocaleLowerCase(),
value: this.model.props.url,
enabled: false
}).component();
@@ -152,12 +147,12 @@ export abstract class HdfsDialogBase<T extends HdfsDialogProperties, R> {
this.authDropdown.onValueChanged(e => this.onAuthChanged());
this.usernameInputBox = this.uiModelBuilder.inputBox()
.withProperties<azdata.InputBoxProperties>({
placeHolder: localize('textUsernameLower', "username"),
placeHolder: loc.username.toLocaleLowerCase(),
value: this.model.props.username
}).component();
this.passwordInputBox = this.uiModelBuilder.inputBox()
.withProperties<azdata.InputBoxProperties>({
placeHolder: localize('textPasswordLower', "password"),
placeHolder: loc.password.toLocaleLowerCase(),
inputType: 'password',
value: this.model.props.password
})
@@ -167,23 +162,23 @@ export abstract class HdfsDialogBase<T extends HdfsDialogProperties, R> {
components: [
{
component: this.urlInputBox,
title: localize('textUrlCapital', "Cluster Management URL"),
title: loc.clusterUrl,
required: true
}, {
component: this.authDropdown,
title: localize('textAuthCapital', "Authentication type"),
title: loc.authType,
required: true
}, {
component: this.usernameInputBox,
title: localize('textUsernameCapital', "Username"),
title: loc.username,
required: false
}, {
component: this.passwordInputBox,
title: localize('textPasswordCapital', "Password"),
title: loc.password,
required: false
}
],
title: localize('hdsf.dialog.connection.section', "Cluster Connection")
title: loc.clusterConnection
};
let formModel = this.uiModelBuilder.formContainer()
.withFormItems(
@@ -204,8 +199,8 @@ export abstract class HdfsDialogBase<T extends HdfsDialogProperties, R> {
return result.validated;
});
this.dialog.cancelButton.onClick(async () => await this.cancel());
this.dialog.okButton.label = localize('hdfs.dialog.ok', "OK");
this.dialog.cancelButton.label = localize('hdfs.dialog.cancel', "Cancel");
this.dialog.okButton.label = loc.ok;
this.dialog.cancelButton.label = loc.cancel;
}
protected abstract getMainSectionComponents(): (azdata.FormComponentGroup | azdata.FormComponent)[];

View File

@@ -5,14 +5,9 @@
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as nls from 'vscode-nls';
import { ClusterController, MountInfo, MountState } from '../controller/clusterControllerApi';
import { HdfsDialogBase, HdfsDialogModelBase, HdfsDialogProperties } from './hdfsDialogBase';
const localize = nls.loadMessageBundle();
const mountConfigutationTitle = localize('mount.main.section', "Mount Configuration");
const hdfsPathTitle = localize('mount.hdfsPath.title', "HDFS Path");
import * as loc from '../localizedConstants';
/**
* Converts a comma-delimited set of key value pair credentials to a JSON object.
@@ -38,7 +33,7 @@ function convertCredsToJson(creds: string): { credentials: {} } {
}
validPairs.forEach(pair => {
const formattingErr = localize('mount.err.formatting', "Bad formatting of credentials at {0}", pair);
const formattingErr = loc.badCredentialsFormatting(pair);
try {
// # remove escaped characters for ,
pair = pair.replace('\\,', ',').trim();
@@ -82,7 +77,7 @@ export class MountHdfsDialogModel extends HdfsDialogModelBase<MountHdfsPropertie
azdata.tasks.startBackgroundOperation(
{
connection: undefined,
displayName: localize('mount.task.name', "Mounting HDFS folder on path {0}", this.props.hdfsPath),
displayName: loc.mountTask(this.props.hdfsPath),
description: '',
isCancelable: false,
operation: op => {
@@ -95,16 +90,15 @@ export class MountHdfsDialogModel extends HdfsDialogModelBase<MountHdfsPropertie
private async onSubmit(controller: ClusterController, op: azdata.BackgroundOperation): Promise<void> {
try {
await controller.mountHdfs(this.props.hdfsPath, this.props.remoteUri, this.credentials);
op.updateStatus(azdata.TaskStatus.InProgress, localize('mount.task.submitted', "Mount creation has started"));
op.updateStatus(azdata.TaskStatus.InProgress, loc.mountTaskSubmitted);
// Wait until status has changed or some sensible time expired. If it goes over 2 minutes we assume it's "working"
// as there's no other API that'll give us this for now
let result = await this.waitOnMountStatusChange(controller);
let msg = result.state === MountState.Ready ? localize('mount.task.complete', "Mounting HDFS folder is complete")
: localize('mount.task.inprogress', "Mounting is likely to complete, check back later to verify");
let msg = result.state === MountState.Ready ? loc.mountCompleted : loc.mountInProgress;
op.updateStatus(azdata.TaskStatus.Succeeded, msg);
} catch (error) {
const errMsg = localize('mount.task.error', "Error mounting folder: {0}", (error instanceof Error ? error.message : error));
const errMsg = loc.mountError(error);
vscode.window.showErrorMessage(errMsg);
op.updateStatus(azdata.TaskStatus.Failed, errMsg);
}
@@ -118,7 +112,7 @@ export class MountHdfsDialogModel extends HdfsDialogModelBase<MountHdfsPropertie
try {
let mountInfo = await this.getMountStatus(controller, this.props.hdfsPath);
if (mountInfo && mountInfo.error || mountInfo.state === MountState.Error) {
reject(new Error(mountInfo.error ? mountInfo.error : localize('mount.error.unknown', "Unknown error occurred during the mount process")));
reject(new Error(mountInfo.error ? mountInfo.error : loc.mountErrorUnknown));
} else if (mountInfo.state === MountState.Ready || retries <= 0) {
resolve(mountInfo);
} else {
@@ -149,7 +143,7 @@ export class MountHdfsDialog extends HdfsDialogBase<MountHdfsProperties, void> {
private credentialsInputBox: azdata.InputBoxComponent;
constructor(model: MountHdfsDialogModel) {
super(localize('mount.dialog.title', "Mount HDFS Folder (preview)"), model);
super(loc.mountFolder, model);
}
protected getMainSectionComponents(): (azdata.FormComponentGroup | azdata.FormComponent)[] {
@@ -177,28 +171,28 @@ export class MountHdfsDialog extends HdfsDialogBase<MountHdfsProperties, void> {
components: [
{
component: this.pathInputBox,
title: hdfsPathTitle,
title: loc.hdfsPath,
required: true,
layout: {
info: localize('mount.hdfsPath.info', "Path to a new (non-existing) directory which you want to associate with the mount")
info: loc.hdfsPathInfo
}
}, {
component: this.remoteUriInputBox,
title: localize('mount.remoteUri.title', "Remote URI"),
title: loc.remoteUri,
required: true,
layout: {
info: localize('mount.remoteUri.info', "The URI to the remote data source. Example for ADLS: abfs://fs@saccount.dfs.core.windows.net/")
info: loc.remoteUriInfo
}
}, {
component: this.credentialsInputBox,
title: localize('mount.credentials.title', "Credentials"),
title: loc.credentials,
required: false,
layout: {
info: localize('mount.credentials.info', "Mount credentials for authentication to remote data source for reads")
info: loc.credentialsInfo
}
}
],
title: mountConfigutationTitle
title: loc.mountConfiguration
}];
}
@@ -225,7 +219,7 @@ export class RefreshMountDialog extends HdfsDialogBase<MountHdfsProperties, void
private pathInputBox: azdata.InputBoxComponent;
constructor(model: RefreshMountModel) {
super(localize('refreshmount.dialog.title', "Refresh Mount"), model);
super(loc.refreshMount, model);
}
protected getMainSectionComponents(): (azdata.FormComponentGroup | azdata.FormComponent)[] {
@@ -238,11 +232,11 @@ export class RefreshMountDialog extends HdfsDialogBase<MountHdfsProperties, void
components: [
{
component: this.pathInputBox,
title: hdfsPathTitle,
title: loc.hdfsPath,
required: true
}
],
title: mountConfigutationTitle
title: loc.mountConfiguration
}];
}
@@ -280,7 +274,7 @@ export class RefreshMountModel extends HdfsDialogModelBase<MountHdfsProperties,
azdata.tasks.startBackgroundOperation(
{
connection: undefined,
displayName: localize('refreshmount.task.name', "Refreshing HDFS Mount on path {0}", this.props.hdfsPath),
displayName: loc.refreshMountTask(this.props.hdfsPath),
description: '',
isCancelable: false,
operation: op => {
@@ -293,7 +287,7 @@ export class RefreshMountModel extends HdfsDialogModelBase<MountHdfsProperties,
private async onSubmit(controller: ClusterController, op: azdata.BackgroundOperation): Promise<void> {
try {
await controller.refreshMount(this.props.hdfsPath);
op.updateStatus(azdata.TaskStatus.Succeeded, localize('refreshmount.task.submitted', "Refresh mount request submitted"));
op.updateStatus(azdata.TaskStatus.Succeeded, loc.refreshMountTaskSubmitted);
} catch (error) {
const errMsg = (error instanceof Error) ? error.message : error;
vscode.window.showErrorMessage(errMsg);
@@ -306,7 +300,7 @@ export class DeleteMountDialog extends HdfsDialogBase<MountHdfsProperties, void>
private pathInputBox: azdata.InputBoxComponent;
constructor(model: DeleteMountModel) {
super(localize('deleteMount.dialog.title', "Delete Mount"), model);
super(loc.deleteMount, model);
}
protected getMainSectionComponents(): (azdata.FormComponentGroup | azdata.FormComponent)[] {
@@ -319,11 +313,11 @@ export class DeleteMountDialog extends HdfsDialogBase<MountHdfsProperties, void>
components: [
{
component: this.pathInputBox,
title: hdfsPathTitle,
title: loc.hdfsPath,
required: true
}
],
title: mountConfigutationTitle
title: loc.mountConfiguration
}];
}
@@ -361,7 +355,7 @@ export class DeleteMountModel extends HdfsDialogModelBase<MountHdfsProperties, v
azdata.tasks.startBackgroundOperation(
{
connection: undefined,
displayName: localize('deletemount.task.name', "Deleting HDFS Mount on path {0}", this.props.hdfsPath),
displayName: loc.deleteMountTask(this.props.hdfsPath),
description: '',
isCancelable: false,
operation: op => {
@@ -374,7 +368,7 @@ export class DeleteMountModel extends HdfsDialogModelBase<MountHdfsProperties, v
private async onSubmit(controller: ClusterController, op: azdata.BackgroundOperation): Promise<void> {
try {
await controller.deleteMount(this.props.hdfsPath);
op.updateStatus(azdata.TaskStatus.Succeeded, localize('deletemount.task.submitted', "Delete mount request submitted"));
op.updateStatus(azdata.TaskStatus.Succeeded, loc.deleteMountTaskSubmitted);
} catch (error) {
const errMsg = (error instanceof Error) ? error.message : error;
vscode.window.showErrorMessage(errMsg);

View File

@@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
import { ControllerError } from './controller/clusterControllerApi';
const localize = nls.loadMessageBundle();
// Labels
export const statusIcon = localize('bdc.dashboard.status', "Status Icon");
export const instance = localize('bdc.dashboard.instance', "Instance");
export const state = localize('bdc.dashboard.state', "State");
export const view = localize('bdc.dashboard.view', "View");
export const notAvailable = localize('bdc.dashboard.notAvailable', "N/A");
export const healthStatusDetails = localize('bdc.dashboard.healthStatusDetails', "Health Status Details");
export const metricsAndLogs = localize('bdc.dashboard.metricsAndLogs', "Metrics and Logs");
export const healthStatus = localize('bdc.dashboard.healthStatus', "Health Status");
export const nodeMetrics = localize('bdc.dashboard.nodeMetrics', "Node Metrics");
export const sqlMetrics = localize('bdc.dashboard.sqlMetrics', "SQL Metrics");
export const logs = localize('bdc.dashboard.logs', "Logs");
export function lastUpdated(date?: Date): string {
return localize('bdc.dashboard.lastUpdated', "Last Updated : {0}",
date ?
`${date.toLocaleDateString()} ${date.toLocaleTimeString()}`
: '-');
}
export const basic = localize('basicAuthName', "Basic");
export const windowsAuth = localize('integratedAuthName', "Windows Authentication");
export const addNewController = localize('addNewController', "Add New Controller (preview)");
export const url = localize('url', "URL");
export const username = localize('username', "Username");
export const password = localize('password', "Password");
export const rememberPassword = localize('rememberPassword', "Remember Password");
export const clusterUrl = localize('clusterManagementUrl', "Cluster Management URL");
export const authType = localize('textAuthCapital', "Authentication type");
export const clusterConnection = localize('hdsf.dialog.connection.section', "Cluster Connection");
export const add = localize('add', "Add");
export const cancel = localize('cancel', "Cancel");
export const ok = localize('ok', "OK");
export const refresh = localize('bdc.dashboard.refresh', "Refresh");
export const troubleshoot = localize('bdc.dashboard.troubleshoot', "Troubleshoot");
export const bdcOverview = localize('bdc.dashboard.bdcOverview', "Big Data Cluster overview");
export const clusterDetails = localize('bdc.dashboard.clusterDetails', "Cluster Details");
export const clusterOverview = localize('bdc.dashboard.clusterOverview', "Cluster Overview");
export const serviceEndpoints = localize('bdc.dashboard.serviceEndpoints', "Service Endpoints");
export const clusterProperties = localize('bdc.dashboard.clusterProperties', "Cluster Properties");
export const clusterState = localize('bdc.dashboard.clusterState', "Cluster State :");
export const healthStatusWithColon = localize('bdc.dashboard.healthStatusWithColon', "Health Status :");
export const serviceName = localize('bdc.dashboard.serviceName', "Service Name");
export const service = localize('bdc.dashboard.service', "Service");
export const endpoint = localize('bdc.dashboard.endpoint', "Endpoint");
export function copiedEndpoint(endpointName: string): string { return localize('copiedEndpoint', "Endpoint '{0}' copied to clipboard", endpointName); }
export const copy = localize('bdc.dashboard.copy', "Copy");
export const viewDetails = localize('bdc.dashboard.viewDetails', "View Details");
export const connectToController = localize('connectController.dialog.title', "Connect to Controller (preview)");
export const mountConfiguration = localize('mount.main.section', "Mount Configuration");
export function mountTask(path: string): string { return localize('mount.task.name', "Mounting HDFS folder on path {0}", path); }
export function refreshMountTask(path: string): string { return localize('refreshmount.task.name', "Refreshing HDFS Mount on path {0}", path); }
export function deleteMountTask(path: string): string { return localize('deletemount.task.name', "Deleting HDFS Mount on path {0}", path); }
export const mountTaskSubmitted = localize('mount.task.submitted', "Mount creation has started");
export const refreshMountTaskSubmitted = localize('refreshmount.task.submitted', "Refresh mount request submitted");
export const deleteMountTaskSubmitted = localize('deletemount.task.submitted', "Delete mount request submitted");
export const mountCompleted = localize('mount.task.complete', "Mounting HDFS folder is complete");
export const mountInProgress = localize('mount.task.inprogress', "Mounting is likely to complete, check back later to verify");
export const mountFolder = localize('mount.dialog.title', "Mount HDFS Folder (preview)");
export const hdfsPath = localize('mount.hdfsPath.title', "HDFS Path");
export const hdfsPathInfo = localize('mount.hdfsPath.info', "Path to a new (non-existing) directory which you want to associate with the mount");
export const remoteUri = localize('mount.remoteUri.title', "Remote URI");
export const remoteUriInfo = localize('mount.remoteUri.info', "The URI to the remote data source. Example for ADLS: abfs://fs@saccount.dfs.core.windows.net/");
export const credentials = localize('mount.credentials.title', "Credentials");
export const credentialsInfo = localize('mount.credentials.info', "Mount credentials for authentication to remote data source for reads");
export const refreshMount = localize('refreshmount.dialog.title', "Refresh Mount");
export const deleteMount = localize('deleteMount.dialog.title', "Delete Mount");
// Errors
export const usernameRequired = localize('err.controller.username.required', "Username is required");
export const passwordRequired = localize('err.controller.password.required', "Password is required");
export function endpointsError(msg: string): string { return localize('endpointsError', "Unexpected error retrieving BDC Endpoints: {0}", msg); }
export const noConnectionError = localize('bdc.dashboard.noConnection', "The dashboard requires a connection. Please click retry to enter your credentials.");
export function unexpectedError(error: Error): string { return localize('bdc.dashboard.unexpectedError', "Unexpected error occurred: {0}", error.message); }
export const loginFailed = localize('mount.hdfs.loginerror1', "Login to controller failed");
export function loginFailedWithError(error: ControllerError): string { return localize('mount.hdfs.loginerror2', "Login to controller failed: {0}", error.statusMessage || error.message); }
export function badCredentialsFormatting(pair: string): string { return localize('mount.err.formatting', "Bad formatting of credentials at {0}", pair); }
export function mountError(error: any): string { return localize('mount.task.error', "Error mounting folder: {0}", (error instanceof Error ? error.message : error)); }
export const mountErrorUnknown = localize('mount.error.unknown', "Unknown error occurred during the mount process");

View File

@@ -90,6 +90,7 @@ declare module 'azdata' {
export interface DeclarativeTableColumn {
headerCssStyles?: { [key: string]: string };
rowCssStyles?: { [key: string]: string };
ariaLabel?: string;
}
export enum DeclarativeDataType {
@@ -122,4 +123,7 @@ declare module 'azdata' {
export enum AzureResource {
OssRdbms = 2
}
export interface DeclarativeTableProperties extends ComponentProperties {
}
}

View File

@@ -31,7 +31,7 @@ export enum DeclarativeDataType {
<table role=grid #container *ngIf="columns" class="declarative-table" [style.height]="getHeight()" [attr.aria-label]="ariaLabel">
<thead>
<ng-container *ngFor="let column of columns;">
<th class="declarative-table-header" tabindex="-1" aria-sort="none" [ngStyle]="column.headerCssStyles">{{column.displayName}}</th>
<th class="declarative-table-header" tabindex="-1" aria-sort="none" [attr.aria-label]="column.ariaLabel" [ngStyle]="column.headerCssStyles">{{column.displayName}}</th>
</ng-container>
</thead>
<ng-container *ngIf="data">