mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 09:35:37 -05:00
fix up backup dialog for accessibility (#1155)
This commit is contained in:
@@ -8,24 +8,24 @@
|
||||
<div class="angular-modal-body" style="display: flex; flex-direction: column;">
|
||||
<div class="angular-modal-body-content">
|
||||
<div class="dialog-label">
|
||||
{{backupNameLabel}}
|
||||
{{localizedStrings.BACKUP_NAME}}
|
||||
</div>
|
||||
<div class="input-divider" #backupsetName>
|
||||
</div>
|
||||
<div class="dialog-label">
|
||||
{{recoveryModelLabel}}
|
||||
{{localizedStrings.RECOVERY_MODEL}}
|
||||
</div>
|
||||
<div class="input-divider" #recoveryModelContainer>
|
||||
</div>
|
||||
<div class="dialog-label">
|
||||
{{backupTypeLabel}}
|
||||
{{localizedStrings.BACKUP_TYPE}}
|
||||
</div>
|
||||
<div class="input-divider" #backupTypeContainer>
|
||||
</div>
|
||||
<div class="input-divider check" #copyOnlyContainer>
|
||||
</div>
|
||||
<div class="dialog-label">
|
||||
{{backupDeviceLabel}}
|
||||
{{localizedStrings.BACKUP_DEVICE}}
|
||||
</div>
|
||||
<div class="backup-path-list">
|
||||
<div #pathContainer>
|
||||
@@ -47,11 +47,11 @@
|
||||
<div class="advanced-main-body" #advancedOptionBodyContainer>
|
||||
<!-- Compression -->
|
||||
<div class="dialog-label advanced-header">
|
||||
{{compressionLabel}}
|
||||
{{localizedStrings.COMPRESSION}}
|
||||
</div>
|
||||
<div class="indent">
|
||||
<div class="dialog-label">
|
||||
{{setBackupCompressionLabel}}
|
||||
{{localizedStrings.SET_BACKUP_COMPRESSION}}
|
||||
</div>
|
||||
<div class="dialog-label" #compressionContainer>
|
||||
</div>
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
<!-- Encryption -->
|
||||
<div class="dialog-label advanced-header">
|
||||
{{encryptionLabel}}
|
||||
{{localizedStrings.ENCRYPTION}}
|
||||
</div>
|
||||
<div class="indent">
|
||||
<div class="option check" #encryptCheckContainer>
|
||||
@@ -68,17 +68,17 @@
|
||||
<div class="icon warning">
|
||||
</div>
|
||||
<div class="warning-message">
|
||||
{{noEncryptorWarning}}
|
||||
{{localizedStrings.NO_ENCRYPTOR_WARNING}}
|
||||
</div>
|
||||
</div>
|
||||
<div #encryptContainer>
|
||||
<div class="dialog-label">
|
||||
{{algorithmLabel}}
|
||||
{{localizedStrings.ALGORITHM}}
|
||||
</div>
|
||||
<div class="dialog-label" #algorithmContainer>
|
||||
</div>
|
||||
<div class="dialog-label">
|
||||
{{certificateOrAsymmetricKeyLabel}}
|
||||
{{localizedStrings.CERTIFICATE_OR_ASYMMETRIC_KEY}}
|
||||
</div>
|
||||
<div class="dialog-label" #encryptorContainer>
|
||||
</div>
|
||||
@@ -86,33 +86,33 @@
|
||||
</div>
|
||||
|
||||
<!-- Overwrite media -->
|
||||
<div class="dialog-label advanced-header">
|
||||
{{mediaLabel}}
|
||||
<div id="media" class="dialog-label advanced-header">
|
||||
{{localizedStrings.MEDIA}}
|
||||
</div>
|
||||
<div class="radio-indent">
|
||||
<div role="radiogroup" aria-labelledby="media" class="radio-indent">
|
||||
<div class="option">
|
||||
<input type="radio" name=media-option value="no_format" [checked]="!isFormatChecked" (change)="onChangeMediaFormat()" [disabled]="isEncryptChecked">{{mediaOptionLabel}}
|
||||
<input role="radio" type="radio" name="media-option" value="no_format" [checked]="!isFormatChecked" (change)="onChangeMediaFormat()" [disabled]="isEncryptChecked" aria-labelledby="mediaOption"><span id="mediaOption">{{localizedStrings.MEDIA_OPTION}}</span>
|
||||
</div>
|
||||
<div style="margin-left:15px">
|
||||
<div role="radiogroup" aria-labelledby="mediaOption" style="margin-left:15px">
|
||||
<div class="option">
|
||||
<input type="radio" name=existing-media value="append" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked">{{existingMediaAppendLabel}}
|
||||
<input role="radio" type="radio" name="existing-media" value="append" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked" aria-labelledby="existingMediaAppend"><span id="existingMediaAppend">{{localizedStrings.EXISTING_MEDIA_APPEND}}</span>
|
||||
</div>
|
||||
<div class="option">
|
||||
<input type="radio" name=existing-media value="overwrite" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked">{{existingMediaOverwriteLabel}}
|
||||
<input role="radio" type="radio" name="existing-media" value="overwrite" [(ngModel)]="selectedInitOption" [disabled]="isFormatChecked" aria-labelledby="existingMediaOverwrite"><span id="existingMediaOverwrite">{{localizedStrings.EXISTING_MEDIA_OVERWRITE}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option">
|
||||
<input type="radio" name=media-option value="format" [checked]="isFormatChecked" (change)="onChangeMediaFormat()">{{mediaOptionFormatLabel}}
|
||||
<input role="radio" type="radio" name="media-option" value="format" [checked]="isFormatChecked" (change)="onChangeMediaFormat()" aria-labelledby="mediaOptionFormat"><span id="mediaOptionFormat">{{localizedStrings.MEDIA_OPTION_FORMAT}}</span>
|
||||
</div>
|
||||
<div style="margin-left: 22px">
|
||||
<div class="dialog-label">
|
||||
{{newMediaSetNameLabel}}
|
||||
{{localizedStrings.NEW_MEDIA_SET_NAME}}
|
||||
</div>
|
||||
<div class="dialog-label" #mediaName>
|
||||
</div>
|
||||
<div class="dialog-label">
|
||||
{{newMediaSetDescriptionLabel}}
|
||||
{{localizedStrings.NEW_MEDIA_SET_DESCRIPTION}}
|
||||
</div>
|
||||
<div class="dialog-label" #mediaDescription>
|
||||
</div>
|
||||
@@ -120,21 +120,21 @@
|
||||
</div>
|
||||
|
||||
<!-- Transaction log -->
|
||||
<div class="dialog-label advanced-header">
|
||||
{{transactionLogLabel}}
|
||||
<div id="transactionLog" class="dialog-label advanced-header">
|
||||
{{localizedStrings.TRANSACTION_LOG}}
|
||||
</div>
|
||||
<div class="radio-indent">
|
||||
<div role="radiogroup" aria-labelledby="transactionLog" class="radio-indent">
|
||||
<div class="option">
|
||||
<input type="radio" name=t-log value="truncate" [checked]="isTruncateChecked" (change)="onChangeTlog()" [disabled]="disableTlog">Truncate the transaction log
|
||||
<input role="radio" type="radio" name="t-log" value="truncate" [checked]="isTruncateChecked" (change)="onChangeTlog()" [disabled]="disableTlog" aria-labelledby="truncateTransaction"><span id="truncateTransaction">{{localizedStrings.TRUNCATE_TRANSACTION_LOG}}</span>
|
||||
</div>
|
||||
<div class="option">
|
||||
<input type="radio" name=t-log value="taillog" [checked]="isTaillogChecked" (change)="onChangeTlog()" [disabled]="disableTlog">Backup the tail of the log
|
||||
<input role="radio" type="radio" name="t-log" value="taillog" [checked]="isTaillogChecked" (change)="onChangeTlog()" [disabled]="disableTlog" aria-labelledby="backupTail"><span id="backupTail">{{localizedStrings.BACKUP_TAIL}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reliability -->
|
||||
<div class="dialog-label advanced-header">
|
||||
{{reliabilityLabel}}
|
||||
{{localizedStrings.RELIABILITY}}
|
||||
</div>
|
||||
<div class="indent">
|
||||
<div class="option check" #checksumContainer>
|
||||
@@ -147,11 +147,11 @@
|
||||
|
||||
<!-- Backup expiration -->
|
||||
<div class="dialog-label advanced-header">
|
||||
{{expirationLabel}}
|
||||
{{localizedStrings.EXPIRATION}}
|
||||
</div>
|
||||
<div class="indent">
|
||||
<div class="dialog-label">
|
||||
{{setBackupRetainDaysLabel}}
|
||||
{{localizedStrings.SET_BACKUP_RETAIN_DAYS}}
|
||||
</div>
|
||||
<div class="dialog-label">
|
||||
<div #backupDaysContainer></div>
|
||||
|
||||
@@ -76,6 +76,38 @@ interface MssqlBackupInfo {
|
||||
encryptorName: string;
|
||||
}
|
||||
|
||||
const LocalizedStrings = {
|
||||
BACKUP_NAME: localize('backup.backupName', 'Backup name'),
|
||||
RECOVERY_MODEL: localize('backup.recoveryModel', 'Recovery model'),
|
||||
BACKUP_TYPE: localize('backup.backupType', 'Backup type'),
|
||||
BACKUP_DEVICE: localize('backup.backupDevice', 'Backup files'),
|
||||
ALGORITHM: localize('backup.algorithm', 'Algorithm'),
|
||||
CERTIFICATE_OR_ASYMMETRIC_KEY: localize('backup.certificateOrAsymmetricKey', 'Certificate or Asymmetric key'),
|
||||
MEDIA: localize('backup.media', 'Media'),
|
||||
MEDIA_OPTION: localize('backup.mediaOption', 'Backup to the existing media set'),
|
||||
MEDIA_OPTION_FORMAT: localize('backup.mediaOptionFormat', 'Backup to a new media set'),
|
||||
EXISTING_MEDIA_APPEND: localize('backup.existingMediaAppend', 'Append to the existing backup set'),
|
||||
EXISTING_MEDIA_OVERWRITE: localize('backup.existingMediaOverwrite', 'Overwrite all existing backup sets'),
|
||||
NEW_MEDIA_SET_NAME: localize('backup.newMediaSetName', 'New media set name'),
|
||||
NEW_MEDIA_SET_DESCRIPTION: localize('backup.newMediaSetDescription', 'New media set description'),
|
||||
CHECKSUM_CONTAINER: localize('backup.checksumContainer', 'Perform checksum before writing to media'),
|
||||
VERIFY_CONTAINER: localize('backup.verifyContainer', 'Verify backup when finished'),
|
||||
CONTINUE_ON_ERROR_CONTAINER: localize('backup.continueOnErrorContainer', 'Continue on error'),
|
||||
EXPIRATION: localize('backup.expiration', 'Expiration'),
|
||||
SET_BACKUP_RETAIN_DAYS: localize('backup.setBackupRetainDays', 'Set backup retain days'),
|
||||
COPY_ONLY: localize('backup.copyOnly', 'Copy-only backup'),
|
||||
ADVANCED_CONFIGURATION: localize('backup.advancedConfiguration', 'Advanced Configuration'),
|
||||
COMPRESSION: localize('backup.compression', 'Compression'),
|
||||
SET_BACKUP_COMPRESSION: localize('backup.setBackupCompression', 'Set backup compression'),
|
||||
ENCRYPTION: localize('backup.encryption', 'Encryption'),
|
||||
TRANSACTION_LOG: localize('backup.transactionLog', 'Transaction log'),
|
||||
TRUNCATE_TRANSACTION_LOG: localize('backup.truncateTransactionLog', 'Truncate the transaction log'),
|
||||
BACKUP_TAIL: localize('backup.backupTail', 'Backup the tail of the log'),
|
||||
RELIABILITY: localize('backup.reliability', 'Reliability'),
|
||||
MEDIA_NAME_REQUIRED_ERROR: localize('backup.mediaNameRequired', 'Media name is required'),
|
||||
NO_ENCRYPTOR_WARNING: localize('backup.noEncryptorWarning', "No certificate or asymmetric key is available")
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: BACKUP_SELECTOR,
|
||||
templateUrl: decodeURI(require.toUrl('sql/parts/disasterRecovery/backup/backup.component.html'))
|
||||
@@ -109,36 +141,7 @@ export class BackupComponent {
|
||||
@ViewChild('advancedOptionContainer', { read: ElementRef }) advancedOptionElement;
|
||||
@ViewChild('advancedOptionBodyContainer', { read: ElementRef }) advancedOptionBodyElement;
|
||||
|
||||
// tslint:disable:no-unused-variable
|
||||
private readonly backupNameLabel: string = localize('backup.backupName', 'Backup name');
|
||||
private readonly recoveryModelLabel: string = localize('backup.recoveryModel', 'Recovery model');
|
||||
private readonly backupTypeLabel: string = localize('backup.backupType', 'Backup type');
|
||||
private readonly backupDeviceLabel: string = localize('backup.backupDevice', 'Backup files');
|
||||
private readonly algorithmLabel: string = localize('backup.algorithm', 'Algorithm');
|
||||
private readonly certificateOrAsymmetricKeyLabel: string = localize('backup.certificateOrAsymmetricKey', 'Certificate or Asymmetric key');
|
||||
private readonly mediaLabel: string = localize('backup.media', 'Media');
|
||||
private readonly mediaOptionLabel: string = localize('backup.mediaOption', 'Backup to the existing media set');
|
||||
private readonly mediaOptionFormatLabel: string = localize('backup.mediaOptionFormat', 'Backup to a new media set');
|
||||
private readonly existingMediaAppendLabel: string = localize('backup.existingMediaAppend', 'Append to the existing backup set');
|
||||
private readonly existingMediaOverwriteLabel: string = localize('backup.existingMediaOverwrite', 'Overwrite all existing backup sets');
|
||||
private readonly newMediaSetNameLabel: string = localize('backup.newMediaSetName', 'New media set name');
|
||||
private readonly newMediaSetDescriptionLabel: string = localize('backup.newMediaSetDescription', 'New media set description');
|
||||
private readonly checksumContainerLabel: string = localize('backup.checksumContainer', 'Perform checksum before writing to media');
|
||||
private readonly verifyContainerLabel: string = localize('backup.verifyContainer', 'Verify backup when finished');
|
||||
private readonly continueOnErrorContainerLabel: string = localize('backup.continueOnErrorContainer', 'Continue on error');
|
||||
private readonly expirationLabel: string = localize('backup.expiration', 'Expiration');
|
||||
private readonly setBackupRetainDaysLabel: string = localize('backup.setBackupRetainDays', 'Set backup retain days');
|
||||
private readonly copyOnlyLabel: string = localize('backup.copyOnly', 'Copy-only backup');
|
||||
private readonly advancedConfigurationLabel: string = localize('backup.advancedConfiguration', 'Advanced Configuration');
|
||||
private readonly compressionLabel: string = localize('backup.compression', 'Compression');
|
||||
private readonly setBackupCompressionLabel: string = localize('backup.setBackupCompression', 'Set backup compression');
|
||||
private readonly encryptionLabel: string = localize('backup.encryption', 'Encryption');
|
||||
private readonly transactionLogLabel: string = localize('backup.transactionLog', 'Transaction log');
|
||||
private readonly reliabilityLabel: string = localize('backup.reliability', 'Reliability');
|
||||
private readonly mediaNameRequiredError: string = localize('backup.mediaNameRequired', 'Media name is required');
|
||||
private readonly noEncryptorWarning: string = localize('backup.noEncryptorWarning', "No certificate or asymmetric key is available");
|
||||
|
||||
// tslint:enable:no-unused-variable
|
||||
private localizedStrings = LocalizedStrings;
|
||||
|
||||
private _backupService: IBackupService;
|
||||
private _backupUiService: IBackupUiService;
|
||||
@@ -209,7 +212,7 @@ export class BackupComponent {
|
||||
|
||||
this.recoveryBox = new InputBox(this.recoveryModelElement.nativeElement, this._bootstrapService.contextViewService, {
|
||||
placeholder: this.recoveryModel,
|
||||
ariaLabel: this.recoveryModelLabel
|
||||
ariaLabel: LocalizedStrings.RECOVERY_MODEL
|
||||
});
|
||||
// Set backup type
|
||||
this.backupTypeSelectBox = new SelectBox([], '', this._bootstrapService.contextViewService);
|
||||
@@ -217,47 +220,47 @@ export class BackupComponent {
|
||||
|
||||
// Set copy-only check box
|
||||
this.copyOnlyCheckBox = new Checkbox(this.copyOnlyElement.nativeElement, {
|
||||
label: this.copyOnlyLabel,
|
||||
label: LocalizedStrings.COPY_ONLY,
|
||||
checked: false,
|
||||
onChange: (viaKeyboard) => { },
|
||||
ariaLabel: this.copyOnlyLabel
|
||||
ariaLabel: LocalizedStrings.COPY_ONLY
|
||||
});
|
||||
|
||||
// Encryption checkbox
|
||||
this.encryptCheckBox = new Checkbox(this.encryptElement.nativeElement, {
|
||||
label: this.encryptionLabel,
|
||||
label: LocalizedStrings.ENCRYPTION,
|
||||
checked: false,
|
||||
onChange: (viaKeyboard) => self.onChangeEncrypt(),
|
||||
ariaLabel: this.encryptionLabel
|
||||
ariaLabel: LocalizedStrings.ENCRYPTION
|
||||
});
|
||||
|
||||
// Verify backup checkbox
|
||||
this.verifyCheckBox = new Checkbox(this.verifyElement.nativeElement, {
|
||||
label: this.verifyContainerLabel,
|
||||
label: LocalizedStrings.VERIFY_CONTAINER,
|
||||
checked: false,
|
||||
onChange: (viaKeyboard) => { },
|
||||
ariaLabel: this.verifyContainerLabel
|
||||
ariaLabel: LocalizedStrings.VERIFY_CONTAINER
|
||||
});
|
||||
|
||||
// Perform checksum checkbox
|
||||
this.checksumCheckBox = new Checkbox(this.checksumElement.nativeElement, {
|
||||
label: this.checksumContainerLabel,
|
||||
label: LocalizedStrings.CHECKSUM_CONTAINER,
|
||||
checked: false,
|
||||
onChange: (viaKeyboard) => { },
|
||||
ariaLabel: this.checksumContainerLabel
|
||||
ariaLabel: LocalizedStrings.CHECKSUM_CONTAINER
|
||||
});
|
||||
|
||||
// Continue on error checkbox
|
||||
this.continueOnErrorCheckBox = new Checkbox(this.continueOnErrorElement.nativeElement, {
|
||||
label: this.continueOnErrorContainerLabel,
|
||||
label: LocalizedStrings.CONTINUE_ON_ERROR_CONTAINER,
|
||||
checked: false,
|
||||
onChange: (viaKeyboard) => { },
|
||||
ariaLabel: this.continueOnErrorContainerLabel
|
||||
ariaLabel: LocalizedStrings.CONTINUE_ON_ERROR_CONTAINER
|
||||
});
|
||||
|
||||
// Set backup name
|
||||
this.backupNameBox = new InputBox(this.backupNameElement.nativeElement, this._bootstrapService.contextViewService, {
|
||||
ariaLabel: this.backupNameLabel
|
||||
ariaLabel: LocalizedStrings.BACKUP_NAME
|
||||
});
|
||||
|
||||
// Set backup path list
|
||||
@@ -288,14 +291,14 @@ export class BackupComponent {
|
||||
this._bootstrapService.contextViewService,
|
||||
{
|
||||
validationOptions: {
|
||||
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: this.mediaNameRequiredError }) : null
|
||||
validation: (value: string) => !value ? ({ type: MessageType.ERROR, content: LocalizedStrings.MEDIA_NAME_REQUIRED_ERROR }) : null
|
||||
},
|
||||
ariaLabel: this.newMediaSetNameLabel
|
||||
ariaLabel: LocalizedStrings.NEW_MEDIA_SET_NAME
|
||||
}
|
||||
);
|
||||
|
||||
this.mediaDescriptionBox = new InputBox(this.mediaDescriptionElement.nativeElement, this._bootstrapService.contextViewService, {
|
||||
ariaLabel: this.newMediaSetDescriptionLabel
|
||||
ariaLabel: LocalizedStrings.NEW_MEDIA_SET_DESCRIPTION
|
||||
});
|
||||
|
||||
// Set backup retain days
|
||||
@@ -315,7 +318,7 @@ export class BackupComponent {
|
||||
}
|
||||
}
|
||||
},
|
||||
ariaLabel: this.setBackupRetainDaysLabel
|
||||
ariaLabel: LocalizedStrings.SET_BACKUP_RETAIN_DAYS
|
||||
});
|
||||
|
||||
// Disable elements
|
||||
@@ -331,7 +334,7 @@ export class BackupComponent {
|
||||
// Set category view for advanced options. This should be defined in ngAfterViewInit so that it correctly calculates the text height after data binding.
|
||||
var splitview = new SplitView(this.advancedOptionElement.nativeElement);
|
||||
var advancedBodySize = DOM.getTotalHeight(this.advancedOptionBodyElement.nativeElement);
|
||||
var categoryView = new CategoryView(this.advancedConfigurationLabel, this.advancedOptionBodyElement.nativeElement, true, advancedBodySize, this._advancedHeaderSize);
|
||||
var categoryView = new CategoryView(LocalizedStrings.ADVANCED_CONFIGURATION, this.advancedOptionBodyElement.nativeElement, true, advancedBodySize, this._advancedHeaderSize);
|
||||
splitview.addView(categoryView);
|
||||
splitview.layout(advancedBodySize + this._advancedHeaderSize);
|
||||
|
||||
@@ -599,7 +602,7 @@ export class BackupComponent {
|
||||
if (strings.isFalsyOrWhitespace(this.mediaNameBox.value)) {
|
||||
this.backupEnabled = false;
|
||||
this.backupButton.enabled = false;
|
||||
this.mediaNameBox.showMessage({ type: MessageType.ERROR, content: this.mediaNameRequiredError });
|
||||
this.mediaNameBox.showMessage({ type: MessageType.ERROR, content: LocalizedStrings.MEDIA_NAME_REQUIRED_ERROR });
|
||||
}
|
||||
} else {
|
||||
this.enableBackupButton();
|
||||
|
||||
Reference in New Issue
Block a user