@trudb/tru-common-lib 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -361,7 +361,6 @@ class TruAppEnvironment {
|
|
|
361
361
|
_appName;
|
|
362
362
|
_appDescription;
|
|
363
363
|
_appUri;
|
|
364
|
-
_enablePasswordStrength;
|
|
365
364
|
_backgroundImageUri;
|
|
366
365
|
_environmentWarning;
|
|
367
366
|
_loginFormTitle;
|
|
@@ -397,7 +396,6 @@ class TruAppEnvironment {
|
|
|
397
396
|
this._appName = '';
|
|
398
397
|
this._appDescription = '';
|
|
399
398
|
this._appUri = '';
|
|
400
|
-
this._enablePasswordStrength = true;
|
|
401
399
|
this._backgroundImageUri = '';
|
|
402
400
|
this._environmentWarning = '';
|
|
403
401
|
this._loginFormTitle = '';
|
|
@@ -434,13 +432,6 @@ class TruAppEnvironment {
|
|
|
434
432
|
set appDescription(description) {
|
|
435
433
|
this._appDescription = description;
|
|
436
434
|
}
|
|
437
|
-
get enablePasswordStrength() {
|
|
438
|
-
return this._enablePasswordStrength;
|
|
439
|
-
}
|
|
440
|
-
;
|
|
441
|
-
set enablePasswordStrength(enable) {
|
|
442
|
-
this._enablePasswordStrength = enable;
|
|
443
|
-
}
|
|
444
435
|
get backgroundImageUri() {
|
|
445
436
|
return this._backgroundImageUri;
|
|
446
437
|
}
|
|
@@ -1014,7 +1005,7 @@ class TruPasswordDialog {
|
|
|
1014
1005
|
passwordSuggestions = [];
|
|
1015
1006
|
passwordStrengthLevels = [0, 1, 2, 3, 4];
|
|
1016
1007
|
passwordStrengthLabels = ['Very weak', 'Weak', 'Fair', 'Strong', 'Very strong'];
|
|
1017
|
-
minimumPasswordScore =
|
|
1008
|
+
minimumPasswordScore = 1;
|
|
1018
1009
|
errorMsg = null;
|
|
1019
1010
|
busy = false;
|
|
1020
1011
|
baseUrl = '';
|
|
@@ -1030,9 +1021,6 @@ class TruPasswordDialog {
|
|
|
1030
1021
|
onShowPasswordClicked = () => {
|
|
1031
1022
|
this.showPassword = this.showPasswordControl.value;
|
|
1032
1023
|
};
|
|
1033
|
-
get enablePasswordStrength() {
|
|
1034
|
-
return this.appEnvironment.enablePasswordStrength;
|
|
1035
|
-
}
|
|
1036
1024
|
get validationMessage() {
|
|
1037
1025
|
if (!this.admin && !this.currentPasswordControl.value)
|
|
1038
1026
|
return 'Enter your current password.';
|
|
@@ -1041,10 +1029,9 @@ class TruPasswordDialog {
|
|
|
1041
1029
|
if (!this.confirmNewPasswordControl.value)
|
|
1042
1030
|
return 'Confirm your new password.';
|
|
1043
1031
|
if (this.newPasswordControl.value !== this.confirmNewPasswordControl.value)
|
|
1044
|
-
return '
|
|
1045
|
-
if (this.
|
|
1046
|
-
|
|
1047
|
-
return `Choose a password rated ${this.passwordStrengthLabels[this.minimumPasswordScore]} or stronger.`;
|
|
1032
|
+
return 'Passwords do not match.';
|
|
1033
|
+
if (this.passwordScore === null || this.passwordScore < this.minimumPasswordScore)
|
|
1034
|
+
return 'Choose a stronger password.';
|
|
1048
1035
|
return null;
|
|
1049
1036
|
}
|
|
1050
1037
|
canSubmit = () => !this.busy && this.validationMessage === null;
|
|
@@ -1102,7 +1089,7 @@ class TruPasswordDialog {
|
|
|
1102
1089
|
this.subs.forEach((s) => s.unsubscribe());
|
|
1103
1090
|
}
|
|
1104
1091
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: TruPasswordDialog, deps: [{ token: i1.MatDialogRef }, { token: i1$2.HttpClient }, { token: TruAppEnvironment }, { token: TruUiNotification }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
1105
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: TruPasswordDialog, isStandalone: true, selector: "tru-password-dialog", ngImport: i0, template: "<div mat-dialog-title class=\"mat-dialog-title\">\r\n <p class=\"tru-password-dialog-title\">{{title}}</p>\r\n <p class=\"tru-password-dialog-username\">for {{username}}</p>\r\n</div>\r\n\r\n<div mat-dialog-content class=\"mat-dialog-content tru-control-container tru-password-dialog\">\r\n <p>{{message}}</p>\r\n\r\n <div class=\"tru-password-dialog-control-wrapper\" *ngIf=\"!admin\">\r\n <mat-label>Current Password</mat-label>\r\n <mat-form-field>\r\n <input #currentInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"currentPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n </div>\r\n <div class=\"tru-password-dialog-control-wrapper\">\r\n <mat-label>New Password</mat-label>\r\n <mat-form-field>\r\n <input #newInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"newPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n
|
|
1092
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: TruPasswordDialog, isStandalone: true, selector: "tru-password-dialog", ngImport: i0, template: "<div mat-dialog-title class=\"mat-dialog-title\">\r\n <p class=\"tru-password-dialog-title\">{{title}}</p>\r\n <p class=\"tru-password-dialog-username\">for {{username}}</p>\r\n</div>\r\n\r\n<div mat-dialog-content class=\"mat-dialog-content tru-control-container tru-password-dialog\">\r\n <p>{{message}}</p>\r\n\r\n <div class=\"tru-password-dialog-control-wrapper\" *ngIf=\"!admin\">\r\n <mat-label>Current Password</mat-label>\r\n <mat-form-field>\r\n <input #currentInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"currentPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n </div>\r\n <div class=\"tru-password-dialog-control-wrapper\">\r\n <mat-label>New Password</mat-label>\r\n <mat-form-field>\r\n <input #newInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"newPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n <div class=\"tru-password-strength-meter score-{{passwordScore}}\"\r\n role=\"meter\"\r\n aria-label=\"Password strength\"\r\n aria-valuemin=\"0\"\r\n aria-valuemax=\"4\"\r\n [attr.aria-valuenow]=\"passwordScore\"\r\n [attr.aria-valuetext]=\"passwordScore === null ? 'No password entered' : passwordStrengthLabels[passwordScore]\">\r\n @for (level of passwordStrengthLevels; track level) {\r\n <span [class.active]=\"passwordScore !== null && passwordScore >= level\"></span>\r\n }\r\n </div>\r\n <div class=\"tru-password-feedback\" aria-live=\"polite\">\r\n <p>Minimum strength: {{passwordStrengthLabels[minimumPasswordScore]}} (orange).</p>\r\n @if (passwordScore !== null) {\r\n <p>Strength: {{passwordStrengthLabels[passwordScore]}}.</p>\r\n }\r\n <p *ngIf=\"passwordWarning\">{{passwordWarning}}</p>\r\n @for (suggestion of passwordSuggestions; track suggestion) {\r\n <p>{{suggestion}}</p>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"tru-password-dialog-control-wrapper\">\r\n <mat-label>Confirm New Password</mat-label>\r\n <mat-form-field>\r\n <input #confirmInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"confirmNewPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n </div>\r\n <p class=\"tru-password-dialog-status\" role=\"status\">{{busy ? 'Updating password...' : validationMessage}}</p>\r\n <p class=\"tru-password-dialog-error-msg\" role=\"alert\" *ngIf=\"errorMsg\">{{errorMsg}}</p>\r\n <mat-checkbox [formControl]=\"showPasswordControl\"\r\n (click)=\"onShowPasswordClicked()\"\r\n [labelPosition]=\"'before'\">\r\n Show Password\r\n </mat-checkbox>\r\n</div>\r\n\r\n<div mat-dialog-actions class=\"mat-dialog-actions\">\r\n <button mat-raised-button (click)=\"onDismiss()\">Cancel</button>\r\n <button [disabled]=\"!canSubmit()\" mat-raised-button color=\"primary\" (click)=\"onConfirm()\">Submit</button>\r\n</div>\r\n", styles: ["", "::ng-deep .mat-mdc-dialog-surface{padding:20px}.mat-mdc-dialog-title:before{content:unset!important;height:unset!important;padding:0 0 10px!important}.mdc-dialog__title{padding:20px 0 10px!important}.mdc-dialog__content{padding:10px 0 15px!important;overflow-x:hidden;overflow-y:auto}.mat-mdc-dialog-content p{margin-bottom:0;font-size:14px;color:#545454}.mat-mdc-dialog-actions{padding:0!important}.mat-mdc-dialog-actions button{margin-right:10px}.tru-password-dialog .tru-password-dialog-control-wrapper{margin-bottom:20px}.tru-password-dialog-title{font-size:26px}.tru-password-dialog-username{font-size:14px;margin:0;color:var(--mat-dialog-supporting-text-color, rgba(0, 0, 0, .6))}.tru-password-dialog-error-msg{color:red!important;font-size:11px!important}.tru-password-feedback,.tru-password-dialog-status{margin:8px 0}.tru-password-strength-meter{display:flex;gap:4px;margin-top:4px}.tru-password-strength-meter span{background-color:#ddd;flex:1;height:4px}.tru-password-strength-meter.score-0 span.active{background-color:#d32f2f}.tru-password-strength-meter.score-1 span.active{background-color:#f57c00}.tru-password-strength-meter.score-2 span.active{background-color:#fbc02d}.tru-password-strength-meter.score-3 span.active{background-color:#7cb342}.tru-password-strength-meter.score-4 span.active{background-color:#388e3c}mat-checkbox{float:right!important}.std-control.edit{margin-bottom:10px;margin-right:10px}::ng-deep .tru-password-dialog .mat-mdc-form-field{display:inline!important}::ng-deep .tru-password-dialog .mat-mdc-form-field-infix{padding:0!important;min-height:unset!important}::ng-deep .tru-password-dialog mat-label{font-size:14px;font-weight:700}::ng-deep .tru-password-dialog input{font-size:12px;padding-left:5px}::ng-deep .tru-password-dialog .mat-mdc-form-field-bottom-align:before{content:unset!important}::ng-deep .tru-password-dialog path{color:#a9a9a9}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i8.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MaterialModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
|
|
1106
1093
|
}
|
|
1107
1094
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: TruPasswordDialog, decorators: [{
|
|
1108
1095
|
type: Component,
|
|
@@ -1111,7 +1098,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
1111
1098
|
FormsModule,
|
|
1112
1099
|
ReactiveFormsModule,
|
|
1113
1100
|
MaterialModule,
|
|
1114
|
-
], template: "<div mat-dialog-title class=\"mat-dialog-title\">\r\n <p class=\"tru-password-dialog-title\">{{title}}</p>\r\n <p class=\"tru-password-dialog-username\">for {{username}}</p>\r\n</div>\r\n\r\n<div mat-dialog-content class=\"mat-dialog-content tru-control-container tru-password-dialog\">\r\n <p>{{message}}</p>\r\n\r\n <div class=\"tru-password-dialog-control-wrapper\" *ngIf=\"!admin\">\r\n <mat-label>Current Password</mat-label>\r\n <mat-form-field>\r\n <input #currentInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"currentPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n </div>\r\n <div class=\"tru-password-dialog-control-wrapper\">\r\n <mat-label>New Password</mat-label>\r\n <mat-form-field>\r\n <input #newInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"newPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n
|
|
1101
|
+
], template: "<div mat-dialog-title class=\"mat-dialog-title\">\r\n <p class=\"tru-password-dialog-title\">{{title}}</p>\r\n <p class=\"tru-password-dialog-username\">for {{username}}</p>\r\n</div>\r\n\r\n<div mat-dialog-content class=\"mat-dialog-content tru-control-container tru-password-dialog\">\r\n <p>{{message}}</p>\r\n\r\n <div class=\"tru-password-dialog-control-wrapper\" *ngIf=\"!admin\">\r\n <mat-label>Current Password</mat-label>\r\n <mat-form-field>\r\n <input #currentInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"currentPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n </div>\r\n <div class=\"tru-password-dialog-control-wrapper\">\r\n <mat-label>New Password</mat-label>\r\n <mat-form-field>\r\n <input #newInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"newPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n <div class=\"tru-password-strength-meter score-{{passwordScore}}\"\r\n role=\"meter\"\r\n aria-label=\"Password strength\"\r\n aria-valuemin=\"0\"\r\n aria-valuemax=\"4\"\r\n [attr.aria-valuenow]=\"passwordScore\"\r\n [attr.aria-valuetext]=\"passwordScore === null ? 'No password entered' : passwordStrengthLabels[passwordScore]\">\r\n @for (level of passwordStrengthLevels; track level) {\r\n <span [class.active]=\"passwordScore !== null && passwordScore >= level\"></span>\r\n }\r\n </div>\r\n <div class=\"tru-password-feedback\" aria-live=\"polite\">\r\n <p>Minimum strength: {{passwordStrengthLabels[minimumPasswordScore]}} (orange).</p>\r\n @if (passwordScore !== null) {\r\n <p>Strength: {{passwordStrengthLabels[passwordScore]}}.</p>\r\n }\r\n <p *ngIf=\"passwordWarning\">{{passwordWarning}}</p>\r\n @for (suggestion of passwordSuggestions; track suggestion) {\r\n <p>{{suggestion}}</p>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"tru-password-dialog-control-wrapper\">\r\n <mat-label>Confirm New Password</mat-label>\r\n <mat-form-field>\r\n <input #confirmInput\r\n matInput\r\n autocomplete=\"off webauthn\"\r\n [formControl]=\"confirmNewPasswordControl\"\r\n [type]=\"showPassword ? 'text' : 'password'\" />\r\n </mat-form-field>\r\n </div>\r\n <p class=\"tru-password-dialog-status\" role=\"status\">{{busy ? 'Updating password...' : validationMessage}}</p>\r\n <p class=\"tru-password-dialog-error-msg\" role=\"alert\" *ngIf=\"errorMsg\">{{errorMsg}}</p>\r\n <mat-checkbox [formControl]=\"showPasswordControl\"\r\n (click)=\"onShowPasswordClicked()\"\r\n [labelPosition]=\"'before'\">\r\n Show Password\r\n </mat-checkbox>\r\n</div>\r\n\r\n<div mat-dialog-actions class=\"mat-dialog-actions\">\r\n <button mat-raised-button (click)=\"onDismiss()\">Cancel</button>\r\n <button [disabled]=\"!canSubmit()\" mat-raised-button color=\"primary\" (click)=\"onConfirm()\">Submit</button>\r\n</div>\r\n", styles: ["::ng-deep .mat-mdc-dialog-surface{padding:20px}.mat-mdc-dialog-title:before{content:unset!important;height:unset!important;padding:0 0 10px!important}.mdc-dialog__title{padding:20px 0 10px!important}.mdc-dialog__content{padding:10px 0 15px!important;overflow-x:hidden;overflow-y:auto}.mat-mdc-dialog-content p{margin-bottom:0;font-size:14px;color:#545454}.mat-mdc-dialog-actions{padding:0!important}.mat-mdc-dialog-actions button{margin-right:10px}.tru-password-dialog .tru-password-dialog-control-wrapper{margin-bottom:20px}.tru-password-dialog-title{font-size:26px}.tru-password-dialog-username{font-size:14px;margin:0;color:var(--mat-dialog-supporting-text-color, rgba(0, 0, 0, .6))}.tru-password-dialog-error-msg{color:red!important;font-size:11px!important}.tru-password-feedback,.tru-password-dialog-status{margin:8px 0}.tru-password-strength-meter{display:flex;gap:4px;margin-top:4px}.tru-password-strength-meter span{background-color:#ddd;flex:1;height:4px}.tru-password-strength-meter.score-0 span.active{background-color:#d32f2f}.tru-password-strength-meter.score-1 span.active{background-color:#f57c00}.tru-password-strength-meter.score-2 span.active{background-color:#fbc02d}.tru-password-strength-meter.score-3 span.active{background-color:#7cb342}.tru-password-strength-meter.score-4 span.active{background-color:#388e3c}mat-checkbox{float:right!important}.std-control.edit{margin-bottom:10px;margin-right:10px}::ng-deep .tru-password-dialog .mat-mdc-form-field{display:inline!important}::ng-deep .tru-password-dialog .mat-mdc-form-field-infix{padding:0!important;min-height:unset!important}::ng-deep .tru-password-dialog mat-label{font-size:14px;font-weight:700}::ng-deep .tru-password-dialog input{font-size:12px;padding-left:5px}::ng-deep .tru-password-dialog .mat-mdc-form-field-bottom-align:before{content:unset!important}::ng-deep .tru-password-dialog path{color:#a9a9a9}\n"] }]
|
|
1115
1102
|
}], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: i1$2.HttpClient }, { type: TruAppEnvironment }, { type: TruUiNotification }, { type: undefined, decorators: [{
|
|
1116
1103
|
type: Inject,
|
|
1117
1104
|
args: [MAT_DIALOG_DATA]
|
|
@@ -7507,7 +7494,17 @@ class TruDataGridClipboard {
|
|
|
7507
7494
|
this.uiNotification = uiNotification;
|
|
7508
7495
|
this.modelPropertyLookup = modelPropertyLookup;
|
|
7509
7496
|
}
|
|
7497
|
+
bindControlEntity = (controlConfig, entity) => {
|
|
7498
|
+
// Off-screen columns may never run their grid value getter. Compound controls bind their child fields.
|
|
7499
|
+
if (controlConfig.subPropertyNames?.length) {
|
|
7500
|
+
controlConfig.subPropertyNames.forEach((name) => this.bindControlEntity(controlConfig[name], entity));
|
|
7501
|
+
}
|
|
7502
|
+
else {
|
|
7503
|
+
controlConfig.entity = entity;
|
|
7504
|
+
}
|
|
7505
|
+
};
|
|
7510
7506
|
formatCellValue = (controlConfig, propertyConfig, entity, value) => {
|
|
7507
|
+
this.bindControlEntity(controlConfig, entity);
|
|
7511
7508
|
if (propertyConfig.typeName === 'rich-text-unbounded')
|
|
7512
7509
|
return this.util.htmlToPlainText(value);
|
|
7513
7510
|
else if (propertyConfig.typeName === 'foreign-key' || propertyConfig.typeName === 'user-foreign-key')
|
|
@@ -7671,26 +7668,38 @@ class TruDataGridClipboard {
|
|
|
7671
7668
|
copyRow = async (tableName, columnDefs, copiedRows, includeHeaders = false, event) => {
|
|
7672
7669
|
if (copiedRows.length) {
|
|
7673
7670
|
let multiRowString = '';
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7671
|
+
try {
|
|
7672
|
+
if (includeHeaders) {
|
|
7673
|
+
let headerRow = [];
|
|
7674
|
+
columnDefs
|
|
7675
|
+
.forEach((columnDef) => {
|
|
7676
|
+
if (!columnDef.pinned)
|
|
7677
|
+
headerRow.push(columnDef.headerName);
|
|
7678
|
+
});
|
|
7679
|
+
multiRowString += headerRow.join('\t') + '\n';
|
|
7680
|
+
}
|
|
7681
|
+
copiedRows.forEach((copiedRow) => {
|
|
7682
|
+
let rowPropertyValues = [];
|
|
7683
|
+
columnDefs
|
|
7684
|
+
.forEach((columnDef) => {
|
|
7685
|
+
let propertyName = columnDef.field;
|
|
7686
|
+
let propertyConfig = copiedRow[propertyName]?.property;
|
|
7687
|
+
if (propertyConfig && !columnDef.pinned)
|
|
7688
|
+
rowPropertyValues.push(this.formatCellValue(copiedRow[propertyName], copiedRow[propertyName].property, copiedRow.$entity, copiedRow.$entity.getProperty(propertyName)));
|
|
7689
|
+
});
|
|
7690
|
+
multiRowString += rowPropertyValues.join('\t') + '\n';
|
|
7691
7691
|
});
|
|
7692
|
-
|
|
7693
|
-
|
|
7692
|
+
}
|
|
7693
|
+
catch (err) {
|
|
7694
|
+
// A failed copy must also invalidate an earlier asynchronous clipboard write.
|
|
7695
|
+
++this.copySequence;
|
|
7696
|
+
this.copiedData = null;
|
|
7697
|
+
this.pendingCopy = null;
|
|
7698
|
+
this.removeBorderAnimation();
|
|
7699
|
+
event?.preventDefault();
|
|
7700
|
+
this.uiNotification.error('Unable to copy the selected rows.', [err instanceof Error ? err.message : String(err)]);
|
|
7701
|
+
return;
|
|
7702
|
+
}
|
|
7694
7703
|
await this.writeClipboard(multiRowString, {
|
|
7695
7704
|
kind: 'rows',
|
|
7696
7705
|
tableName,
|