Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit 111190be authored by Sebastian-Ion TINCU's avatar Sebastian-Ion TINCU
Browse files

Pull request #108: EDELIVERY-13528 Part-1 Runtime Translation Using ngx-translate

Merge in EDELIVERY/smp from feature/EDELIVERY-13528-part-1_runtime-translation-using-ngx-translate-variant to development

* commit 'af993ce5':
  EDELIVERY-13528 Part-1 Runtime Translation Using ngx-translate
  EDELIVERY-13528 Part-1 Runtime Translation Using ngx-translate
  EDELIVERY-13528 Part-1 Runtime Translation Using ngx-translate
  EDELIVERY-13528 Part-1 Runtime Translation Using ngx-translate
  EDELIVERY-13528 Part-2 Runtime Translation Using ngx-translate
  EDELIVERY-13528 Part-1 Runtime Translation Using ngx-translate
parents 7001aa19 af993ce5
No related branches found
No related tags found
No related merge requests found
Pipeline #192291 failed
Showing
with 150 additions and 81 deletions
......@@ -127,6 +127,7 @@ init_smp_properties() {
echo "# SMP init parameters"
echo "smp.security.folder=${SMP_HOME}/smp/"
echo "smp.libraries.folder=${SMP_HOME}/smp-libs"
echo "smp.locale.folder=${SMP_HOME}/locales"
echo "smp.automation.authentication.external.tls.clientCert.enabled=true"
echo "bdmsl.integration.enabled=false"
echo "bdmsl.participant.multidomain.enabled=false"
......
......@@ -241,6 +241,7 @@ init_smp_properties() {
echo "# SMP init parameters"
echo "smp.security.folder=${DATA_DIR}/smp/"
echo "smp.libraries.folder=$SMP_HOME/apache-tomcat-$TOMCAT_VERSION/smp-libs"
echo "smp.locale.folder=$SMP_HOME/apache-tomcat-$TOMCAT_VERSION/locales"
echo "bdmsl.integration.logical.address=${SMP_LOGICAL_ADDRESS:-http://localhost:8080/smp/}"
echo "smp.automation.authentication.external.tls.clientCert.enabled=true"
echo "bdmsl.integration.enabled=true"
......
......@@ -31,6 +31,8 @@
"@codemirror/search": "^6.5.6",
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.28.1",
"@ngx-translate/core": "^15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
"@swimlane/ngx-datatable": "^20.1.0",
"file-saver": "^2.0.5",
"rxjs": "^7.8.1",
......@@ -4795,6 +4797,33 @@
"webpack": "^5.54.0"
}
},
"node_modules/@ngx-translate/core": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-15.0.0.tgz",
"integrity": "sha512-Am5uiuR0bOOxyoercDnAA3rJVizo4RRqJHo8N3RqJ+XfzVP/I845yEnMADykOHvM6HkVm4SZSnJBOiz0Anx5BA==",
"engines": {
"node": "^16.13.0 || >=18.10.0"
},
"peerDependencies": {
"@angular/common": ">=16.0.0",
"@angular/core": ">=16.0.0",
"rxjs": "^6.5.5 || ^7.4.0"
}
},
"node_modules/@ngx-translate/http-loader": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-8.0.0.tgz",
"integrity": "sha512-SFMsdUcmHF5OdZkL1CHEoSAwbP5EbAOPTLLboOCRRoOg21P4GJx+51jxGdJeGve6LSKLf4Pay7BkTwmE6vxYlg==",
"engines": {
"node": "^16.13.0 || >=18.10.0"
},
"peerDependencies": {
"@angular/common": ">=16.0.0",
"@angular/core": ">=16.0.0",
"@ngx-translate/core": ">=15.0.0",
"rxjs": "^6.5.5 || ^7.4.0"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
......@@ -22196,6 +22225,18 @@
"dev": true,
"requires": {}
},
"@ngx-translate/core": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-15.0.0.tgz",
"integrity": "sha512-Am5uiuR0bOOxyoercDnAA3rJVizo4RRqJHo8N3RqJ+XfzVP/I845yEnMADykOHvM6HkVm4SZSnJBOiz0Anx5BA==",
"requires": {}
},
"@ngx-translate/http-loader": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-8.0.0.tgz",
"integrity": "sha512-SFMsdUcmHF5OdZkL1CHEoSAwbP5EbAOPTLLboOCRRoOg21P4GJx+51jxGdJeGve6LSKLf4Pay7BkTwmE6vxYlg==",
"requires": {}
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
......@@ -15,11 +15,14 @@
},
"private": true,
"dependencies": {
"@angular-material-components/datetime-picker": "^16.0.1",
"@angular-material-components/moment-adapter": "^16.0.1",
"@angular/animations": "^16.2.12",
"@angular/cdk": "^16.2.14",
"@angular/common": "^16.2.12",
"@angular/compiler": "^16.2.12",
"@angular/core": "^16.2.12",
"@angular/flex-layout": "^15.0.0-beta.42",
"@angular/forms": "^16.2.12",
"@angular/material": "^16.2.12",
"@angular/material-moment-adapter": "^16.2.14",
......@@ -27,17 +30,16 @@
"@angular/platform-browser-dynamic": "^16.2.12",
"@angular/platform-server": "^16.2.12",
"@angular/router": "^16.2.12",
"@angular/flex-layout": "^15.0.0-beta.42",
"@swimlane/ngx-datatable": "^20.1.0",
"@angular-material-components/datetime-picker": "^16.0.1",
"@angular-material-components/moment-adapter": "^16.0.1",
"@codemirror/view": "^6.28.1",
"@codemirror/search": "^6.5.6",
"@codemirror/commands": "^6.6.0",
"@codemirror/language": "^6.10.2",
"@codemirror/language-data": "^6.5.1",
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/merge": "^6.6.3",
"@codemirror/search": "^6.5.6",
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.28.1",
"@ngx-translate/core": "^15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
"@swimlane/ngx-datatable": "^20.1.0",
"file-saver": "^2.0.5",
"rxjs": "^7.8.1",
"ts-helpers": "^1.1.2",
......@@ -51,6 +53,7 @@
"@types/file-saver": "2.0.7",
"@types/jasmine": "^4.3.1",
"@types/node": "^18.15.6",
"eslint": "^8.36.0",
"hammerjs": "^2.0.8",
"jasmine-core": "4.6.0",
"jasmine-spec-reporter": "7.0.0",
......@@ -59,8 +62,7 @@
"karma-cli": "^2.0.0",
"karma-jasmine": "^5.1.0",
"ng-packagr": "^16.2.3",
"postcss": "^8.4.21",
"eslint": "^8.36.0"
"postcss": "^8.4.21"
},
"peerDependencies": {
"postcss": "^8.4.21"
......
......@@ -6,10 +6,11 @@
<smp-sidenav #sidenav />
<div class="collapse-button">
<button *ngIf="fullMenu" mat-raised-button id="expand_id" (click)="toggleMenu()">
<mat-icon matTooltip="Collapse" [matTooltipPosition]="'right'">chevron_left</mat-icon>Collapse sidebar
<mat-icon matTooltip="{{ 'app.component.tooltip.collapse' | translate }}" [matTooltipPosition]="'right'">chevron_left</mat-icon>
{{ "app.component.button.collapse" | translate }}
</button>
<button *ngIf="!fullMenu" mat-raised-button id="collapse_id" (click)="toggleMenu()">
<mat-icon matTooltip="Expand" [matTooltipPosition]="'right'">chevron_right</mat-icon>
<mat-icon matTooltip="{{ 'app.component.tooltip.expand' | translate }}" [matTooltipPosition]="'right'">chevron_right</mat-icon>
</button>
</div>
</mat-drawer>
......
......@@ -10,6 +10,7 @@ import {SidenavComponent} from "./window/sidenav/sidenav.component";
import {ToolbarComponent} from "./window/toolbar/toolbar.component";
import {ThemeService} from "./common/theme-service/theme.service";
import {UserController} from "./common/services/user-controller";
import {TranslateService} from "@ngx-translate/core";
@Component({
......@@ -35,9 +36,12 @@ export class AppComponent {
private dialog: MatDialog,
private lookups: GlobalLookups,
private themeService: ThemeService,
private translateService: TranslateService,
) {
this.userController = new UserController(this.http, this.lookups, this.dialog);
this.themeService.updateThemeFromLocalStorage();
this.translateService.setDefaultLang("en");
}
isCurrentUserSystemAdmin(): boolean {
......
......@@ -164,6 +164,7 @@ import {
import {
DocumentPropertyDialogComponent
} from "./common/dialogs/document-property-dialog/document-property-dialog.component";
import {NgxTranslateModule} from "./translate/translate.module";
@NgModule({
......@@ -294,6 +295,7 @@ import {
routing,
MatAutocompleteModule,
ClipboardModule,
NgxTranslateModule,
],
providers: [
AdminDomainService,
......
<div style="margin-bottom:10px">
<a class="smpLink hide-show-column" href="#" *ngIf="!columnSelection" (click)="toggleColumnSelection()"
id="columnslinkoff_id" click-stop-propagation>Show columns</a>
id="columnslinkoff_id" click-stop-propagation>{{ "column.selection.link.show" | translate }}</a>
<a class="smpLink hide-show-column" href="#" *ngIf="columnSelection" (click)="toggleColumnSelection()"
id="columnslinkon_id" click-stop-propagation>Hide columns</a>
id="columnslinkon_id" click-stop-propagation>{{ "column.selection.link.hide" | translate }}</a>
</div>
<div *ngIf="columnSelection" style="margin-bottom: 10px;">
......@@ -10,7 +10,7 @@
<mat-checkbox [id]="col.name" (click)='toggle(col)' [(ngModel)]="col.isSelected">{{col.name}}</mat-checkbox>
</div>
<div class="all-none-selection">
<a href="#" class="smpLink" id="all_id" (click)="selectAllColumns()" click-stop-propagation>All</a>
<a href="#" class="smpLink" id="none_id" (click)="selectNoColumns()" click-stop-propagation>None</a>
<a href="#" class="smpLink" id="all_id" (click)="selectAllColumns()" click-stop-propagation>{{ "column.selection.link.all" | translate }}</a>
<a href="#" class="smpLink" id="none_id" (click)="selectNoColumns()" click-stop-propagation>{{ "column.selection.link.none" | translate }}</a>
</div>
</div>
<smp-dialog [title]="'Unsaved data'"
[text]="'Do you want to cancel all unsaved operations?'"
<smp-dialog [title]="'cancel.dialog.title' | translate"
[text]="'cancel.dialog.text' | translate"
[type]="'confirmation'"
[dialogRef]="dialogRef">
</smp-dialog>
......@@ -6,7 +6,7 @@
<mat-dialog-actions>
<button id="closeDialogButton" mat-raised-button color="primary" mat-dialog-close>
<mat-icon>close</mat-icon>
<span>Close</span>
<span>{{ "certificate.dialog.button.close" | translate }}</span>
</button>
</mat-dialog-actions>
......
......@@ -3,6 +3,7 @@ import {MAT_DIALOG_DATA} from '@angular/material/dialog';
import {UntypedFormBuilder} from "@angular/forms";
import {SmpConstants} from "../../../smp.constants";
import {CertificateRo} from "../../model/certificate-ro.model";
import {TranslateService} from "@ngx-translate/core";
@Component({
selector: 'keystore-certificate-dialog',
......@@ -15,9 +16,10 @@ export class CertificateDialogComponent {
constructor(
@Inject(MAT_DIALOG_DATA) public data: any,
private fb: UntypedFormBuilder) {
private fb: UntypedFormBuilder,
private translateService: TranslateService) {
this.formTitle = "Certificate details";
this.translateService.get("certificate.dialog.title").subscribe(title => this.formTitle = title);
this.current = {...data.row}
}
......
......@@ -5,10 +5,10 @@
<mat-dialog-actions>
<button mat-raised-button color="primary" (click)="dialogRef.close(true)" id="yesbuttondialog_id">
<mat-icon>check_circle</mat-icon>
<span>Yes</span>
<span>{{ "confirmation.dialog.button.yes" | translate }}</span>
</button>
<button mat-raised-button color="primary" (click)="dialogRef.close(false)" id="nobuttondialog_id">
<mat-icon>cancel</mat-icon>
<span>No</span>
<span>{{ "confirmation.dialog.button.no" | translate }}</span>
</button>
</mat-dialog-actions>
......@@ -11,28 +11,27 @@
<div *ngIf="!isReadOnly" class="panel" [formGroup]="credentialForm" >
<mat-form-field style="width: 100%">
<mat-label>Description</mat-label>
<mat-label>{{ "credentials.dialog.label.description" | translate }}</mat-label>
<input matInput
formControlName="description"
maxlength="255">
</mat-form-field>
<div style="display: flex;flex-flow: row wrap;">
<mat-checkbox formControlName="active" style="align-self: center; padding-bottom: 1em;padding-right: 2em">
Active
{{ "credentials.dialog.label.active" | translate }}
</mat-checkbox>
<mat-form-field style="flex-grow: 1">
<mat-label>Validity period of the credentials</mat-label>
<mat-label>{{ "credentials.dialog.label.validity" | translate }}</mat-label>
<mat-date-range-input [rangePicker]="dateRangePicker"
[min]="minSelectableDate">
<input matStartDate formControlName="activeFrom" placeholder="Start date">
<input matEndDate formControlName="expireOn" placeholder="End date">
<input matStartDate formControlName="activeFrom" placeholder="{{ 'credentials.dialog.placeholder.start.date' | translate }}">
<input matEndDate formControlName="expireOn" placeholder="{{ 'credentials.dialog.placeholder.end.date' | translate }}">
</mat-date-range-input>
<mat-datepicker-toggle *ngIf="!this.isCertificateType" matIconSuffix [for]="dateRangePicker"></mat-datepicker-toggle>
<mat-date-range-picker #dateRangePicker></mat-date-range-picker>
<smp-field-error *ngIf="credentialForm.controls.activeFrom.hasError('matStartDateInvalid')">Invalid active from
date
<smp-field-error *ngIf="credentialForm.controls.activeFrom.hasError('matStartDateInvalid')">{{ "credentials.dialog.label.invalid.from" | translate}}
</smp-field-error >
<smp-field-error *ngIf="credentialForm.controls.expireOn.hasError('matEndDateInvalid')">Invalid expire on date
<smp-field-error *ngIf="credentialForm.controls.expireOn.hasError('matEndDateInvalid')">{{ "credentials.dialog.label.invalid.expire.on" | translate}}
</smp-field-error >
</mat-form-field>
</div>
......@@ -44,38 +43,38 @@
<label class="custom-file-upload" style="flex-grow: 1">
<input #fileInput type="file" id="custom-file-upload" accept=".cer,.crt,.pem,.der"
(change)="uploadCertificate($event)">
<button id="importButton" mat-flat-button color="primary" (click)="fileInput.click()">Import</button>
<button id="importButton" mat-flat-button color="primary" (click)="fileInput.click()">{{ "credentials.dialog.button.import" | translate }}</button>
</label>
<mat-form-field class="certificate-id" style="width:100%">
<mat-label>SMP certificate ID</mat-label>
<mat-label>{{ "credentials.dialog.label.smp.certificate.id" | translate }}</mat-label>
<input matInput formControlName="certificateId"
id="certificateId_id"
resizeable="true" readonly="true">
</mat-form-field>
<mat-form-field class="certificate-subject" style="width:100%">
<mat-label>Subject Name</mat-label>
<mat-label>{{ "credentials.dialog.label.subject.name" | translate }}</mat-label>
<input matInput formControlName="subject" id="subject_id"
readonly="true">
</mat-form-field>
<mat-form-field style="width: 100%">
<mat-label>Certificate validity period</mat-label>
<mat-label>{{"credentials.dialog.label.certificate.validity.period" | translate }}</mat-label>
<mat-date-range-input>
<input matStartDate formControlName="validFrom" placeholder="Valid from" readonly="true">
<input matEndDate formControlName="validTo" placeholder="Expire On" readonly="true">
<input matStartDate formControlName="validFrom" placeholder="{{ 'credentials.dialog.placeholder.valid.from' | translate }}" readonly="true">
<input matEndDate formControlName="validTo" placeholder="{{ 'credentials.dialog.placeholder.expire.on' | translate }}" readonly="true">
</mat-date-range-input>
<smp-field-error *ngIf="credentialForm.controls.activeFrom.hasError('matStartDateInvalid')">Invalid active from date
<smp-field-error *ngIf="credentialForm.controls.activeFrom.hasError('matStartDateInvalid')">{{ "credentials.dialog.label.invalid.from" | translate}}
</smp-field-error >
<smp-field-error *ngIf="credentialForm.controls.expireOn.hasError('matEndDateInvalid')">Invalid expire on date
<smp-field-error *ngIf="credentialForm.controls.expireOn.hasError('matEndDateInvalid')">{{ "credentials.dialog.label.invalid.expire.on" | translate}}
</smp-field-error >
</mat-form-field>
<mat-form-field class="certificate-issuer" style="width:100%">
<mat-label>Issuer Name</mat-label>
<mat-label>{{ "credentials.dialog.label.issuer.name" | translate }}</mat-label>
<input matInput formControlName="issuer" id="issuer_id"
readonly="true">
</mat-form-field>
<mat-form-field class="certificate-serial-number" style="width:100%">
<mat-label>Serial Number</mat-label>
<mat-label>{{ "credentials.dialog.label.serial.number" | translate }}</mat-label>
<input matInput formControlName="serialNumber"
id="servialNumber_id" readonly="true">
</mat-form-field>
......@@ -87,7 +86,7 @@
<button id="generatedAccessTokenButton" *ngIf="isAccessTokenType && !isReadOnly" [disabled]="!credentialForm.valid " mat-raised-button color="primary"
(click)="generatedAccessToken()">
<mat-icon>key</mat-icon>
<span>Generate new Access token</span>
<span>{{ "credentials.dialog.button.generate.access.token" | translate }}</span>
</button>
......@@ -95,18 +94,18 @@
[disabled]="!credentialForm.valid || !enableCertificateImport" mat-raised-button color="primary"
(click)="storeCertificateCredentials()">
<mat-icon>key</mat-icon>
<span>Save Certificate</span>
<span>{{ "credentials.dialog.button.save.certificate" | translate }}</span>
</button>
<button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
<mat-icon>close</mat-icon>
<span>Close</span>
<span>{{ "credentials.dialog.button.close" | translate }}</span>
</button>
<button id="copyButton" *ngIf="isAccessTokenType && isReadOnly" [cdkCopyToClipboard]="accessTokenValue" mat-raised-button>
<mat-icon>content_copy</mat-icon>
<span>Copy Access token value</span>
<span>{{ "credentials.dialog.button.copy.access.token" | translate }}</span>
</button>
</mat-dialog-actions>
......
......@@ -8,6 +8,8 @@ import {HttpErrorHandlerService} from "../../error/http-error-handler.service";
import {CertificateService} from "../../services/certificate.service";
import {CertificateRo} from "../../model/certificate-ro.model";
import {UserService} from "../../services/user.service";
import {TranslateService} from "@ngx-translate/core";
import {lastValueFrom} from "rxjs";
@Component({
templateUrl: './credential-dialog.component.html',
......@@ -18,7 +20,7 @@ export class CredentialDialogComponent {
public static ACCESS_TOKEN_TYPE: string = "ACCESS_TOKEN";
dateTimeFormat: string = SmpConstants.DATE_TIME_FORMAT;
formTitle: string = "New Access token created";
formTitle: string;
credentialForm: FormGroup;
certificateForm: FormGroup;
......@@ -37,7 +39,8 @@ export class CredentialDialogComponent {
private httpErrorHandlerService: HttpErrorHandlerService,
private certificateService: CertificateService,
public dialogRef: MatDialogRef<CredentialDialogComponent>,
private formBuilder: FormBuilder
private formBuilder: FormBuilder,
private translateService: TranslateService,
) {
dialogRef.disableClose = true;//disable default close operation
this.formTitle = data.formTitle;
......@@ -124,7 +127,7 @@ export class CredentialDialogComponent {
uploadCertificate(event) {
this.newCertFile = null;
const file = event.target.files[0];
this.certificateService.validateCertificate(file).subscribe((res: CertificateRo) => {
this.certificateService.validateCertificate(file).subscribe(async (res: CertificateRo) => {
if (res && res.certificateId) {
this.certificateForm.patchValue({
'subject': res.subject,
......@@ -151,16 +154,19 @@ export class CredentialDialogComponent {
this.newCertFile = file;
} else {
this.clearCertificateData()
this.showErrorMessage("Error occurred while reading certificate. Check if uploaded file has valid certificate type", true)
this.showErrorMessage(await lastValueFrom(this.translateService.get("credentials.dialog.error.read.certificate")), true)
}
},
err => {
async err => {
this.clearCertificateData()
if (this.httpErrorHandlerService.logoutOnInvalidSessionError(err)) {
this.closeDialog();
return;
}
this.showErrorMessage("Error uploading certificate file [" + file.name + "]." + err.error?.errorDescription, true)
this.showErrorMessage(await lastValueFrom(this.translateService.get("credentials.dialog.error.upload.certificate", {
fileName: file.name,
errorDescription: err.error?.errorDescription
})), true);
}
);
}
......@@ -174,12 +180,12 @@ export class CredentialDialogComponent {
generatedAccessToken() {
this.clearAlert();
this.userService.generateUserAccessTokenCredential(this.initCredential).subscribe((response: AccessTokenRo) => {
this.userService.generateUserAccessTokenCredential(this.initCredential).subscribe(async (response: AccessTokenRo) => {
this.accessTokenValue = response.value;
this.showSuccessMessage(
`Token with ID: "${response.identifier}" and value: "${response.value}" was generated!
<br/><br/>Copy the access token's value and save it in a safe space.
You won't be able to see your token's value once you click <b>Close.</b>`)
this.showSuccessMessage(await lastValueFrom(this.translateService.get("credentials.dialog.success.generate.token", {
responseIdentifier: response.identifier,
responseValue: response.value
})));
this.userService.notifyAccessTokenUpdated(response.credential);
this.setDisabled(true);
}, (err) => {
......
......@@ -6,25 +6,25 @@
<div *ngIf="isConfirmationDialog()" class="divTableCell">
<button mat-raised-button color="primary" (click)="dialogRef.close(true)" id="yesbuttondialog_id" tabindex="0">
<mat-icon>check_circle</mat-icon>
<span>Yes</span>
<span>{{ "dialog.button.yes" | translate }}</span>
</button>
<button mat-raised-button color="primary" (click)="dialogRef.close(false)" id="nobuttondialog_id" tabindex="1">
<mat-icon>cancel</mat-icon>
<span>No</span>
<span>{{ "dialog.button.no" | translate }}</span>
</button>
</div>
<div *ngIf="isInformationDialog()" class="divTableCell">
<button mat-raised-button color="primary" (click)="dialogRef.close(true)" id="okbuttondialog_id" tabindex="3">
<mat-icon>warning</mat-icon>
<span>OK</span>
<span>{{ "dialog.button.ok" | translate }}</span>
</button>
</div>
<div *ngIf="isWarningDialog()" class="divTableCell">
<button mat-raised-button color="primary" (click)="dialogRef.close(false)" id="closebuttondialog_id" tabindex="3">
<mat-icon>close</mat-icon>
<span>Close</span>
<span>{{ "dialog.button.close" | translate }}</span>
</button>
</div>
......
......@@ -4,20 +4,20 @@
<mat-form-field appearance="fill"
style="width: 100%"
>
<mat-label>Property name:</mat-label>
<mat-label>{{ "document.property.dialog.label.property.name" | translate }}</mat-label>
<input style="width: 100%;padding: 5px"
matInput
formControlName="property"/>
<div
*ngIf="propertyForm.controls['property'].hasError('notInList')"
style="color:red; font-size: 70%">
The property name already exists!
{{ "document.property.dialog.error.property.already.exists" | translate }}
</div>
</mat-form-field>
<mat-form-field
*ngIf="propertyForm.controls['type'].value !== PropertyValueTypeEnum.BOOLEAN"
appearance="fill" style="width: 100%">
<mat-label>Property value:</mat-label>
<mat-label>{{ "document.property.dialog.label.property.value" | translate }}</mat-label>
<input style="width: 100%;padding: 5px"
matInput [type]="getInputType(propertyForm.controls['type'].value)"
formControlName="value"
......@@ -30,7 +30,7 @@
{{ propertyForm.controls['property'].value }}
</mat-checkbox>
<mat-form-field appearance="fill" style="width: 100%">
<mat-label>Property Description:</mat-label>
<mat-label>{{ "document.property.dialog.label.property.description" | translate }}</mat-label>
<input style="width: 100%;padding: 5px"
matInput
formControlName="desc"
......@@ -38,7 +38,7 @@
</mat-form-field>
<mat-form-field appearance="fill" style="width: 100%">
<mat-label>Property Type:</mat-label>
<mat-label>{{ "document.property.dialog.label.property.type" | translate }}</mat-label>
<mat-select formControlName="type" style="width: 100%">
<mat-option *ngFor="let type of propertyTypes" [value]="type">
{{ propertyValueTypeDescription(type) }}
......@@ -54,13 +54,13 @@
mat-raised-button color="primary" (click)="submitForm()"
[disabled]="!isDirty || !propertyForm.valid">
<mat-icon>check_circle</mat-icon>
<span>OK</span>
<span>{{ "document.property.dialog.button.ok" | translate }}</span>
</button>
<button mat-raised-button color="primary" mat-dialog-close>
<mat-icon>cancel</mat-icon>
<span *ngIf="isReadOnly; else notReadOnly">Close</span>
<span *ngIf="isReadOnly; else notReadOnly">{{ "document.property.dialog.label.close" | translate }}</span>
<ng-template #notReadOnly>
<span>Cancel</span>
<span>{{ "document.property.dialog.button.cancel" | translate }}</span>
</ng-template>
</button>
</mat-dialog-actions>
......@@ -20,6 +20,8 @@ import {PropertyValueTypeEnum} from "../../enums/property-value-type.enum";
import {
PropertyValueTypeEnumUtil
} from "../../enums/utils/PropertyValueTypeEnumUtil";
import {TranslateService} from "@ngx-translate/core";
import {lastValueFrom} from "rxjs";
@Component({
selector: 'document-property-dialog',
......@@ -28,11 +30,9 @@ import {
})
export class DocumentPropertyDialogComponent {
static readonly NEW_MODE: string = 'Create Document Property';
static readonly EDIT_MODE: string = 'Edit Document Property';
public propertyTypes: string[] = Object.keys(PropertyValueTypeEnum)
protected readonly PropertyValueTypeEnum = PropertyValueTypeEnum;
formTitle: string;
formTitle = "";
current: DocumentPropertyRo;
propertyForm: UntypedFormGroup;
disabled: true;
......@@ -59,12 +59,13 @@ export class DocumentPropertyDialogComponent {
private dialogRef: MatDialogRef<DocumentPropertyDialogComponent>,
private alertService: AlertMessageService,
@Inject(MAT_DIALOG_DATA) public data: any,
private fb: UntypedFormBuilder) {
private fb: UntypedFormBuilder,
private translateService: TranslateService) {
this.current = {...data.row};
this.allPropertyNames = data.allPropertyNames;
this.updateTitle();
(async () => this.updateFormTitle())();
this.propertyForm = fb.group({
'property': new UntypedFormControl({value: '', readonly: true}, [
......@@ -88,8 +89,10 @@ export class DocumentPropertyDialogComponent {
return this.current?.readonly;
}
private updateTitle(): void {
this.formTitle = this.isNewItem ? DocumentPropertyDialogComponent.NEW_MODE : DocumentPropertyDialogComponent.EDIT_MODE;
private async updateFormTitle() {
this.formTitle = this.isNewItem
? await lastValueFrom(this.translateService.get("document.property.dialog.title.new.mode"))
: await lastValueFrom(this.translateService.get("document.property.dialog.title.edit.mode"));
}
/**
......
<smp-dialog [title]="'Password about to expire'"
[text]="'Your password is more than three months old. Please change it as soon as possible!'"
<smp-dialog [title]="'expired.password.dialog.title' | translate"
[text]="'expired.password.dialog.text' | translate"
[type]="'information'"
[dialogRef]="dialogRef">
</smp-dialog>
......@@ -11,7 +11,7 @@
<mat-dialog-actions>
<button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
<mat-icon>cancel</mat-icon>
<span>Close</span>
<span>{{ "manage.members.dialog.button.close" | translate }}</span>
</button>
</mat-dialog-actions>
......
......@@ -2,7 +2,7 @@ import {Component, Inject, Input, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
import {MembershipRoleEnum} from "../../enums/membership-role.enum";
import {Observable} from "rxjs";
import {lastValueFrom, Observable} from "rxjs";
import {SearchUserRo} from "../../model/search-user-ro.model";
import {MembershipService} from "../../panels/membership-panel/membership.service";
import {MemberRo} from "../../model/member-ro.model";
......@@ -11,6 +11,7 @@ import {MemberTypeEnum} from "../../enums/member-type.enum";
import {AlertMessageService} from "../../alert-message/alert-message.service";
import {GroupRo} from "../../model/group-ro.model";
import {ResourceRo} from "../../model/resource-ro.model";
import {TranslateService} from "@ngx-translate/core";
@Component({
......@@ -23,6 +24,7 @@ export class ManageMembersDialogComponent implements OnInit {
message: string;
messageType: string = "alert-error";
formTitle = "";
currentFilter: string;
......@@ -43,7 +45,8 @@ export class ManageMembersDialogComponent implements OnInit {
private membershipService: MembershipService,
public dialogRef: MatDialogRef<ManageMembersDialogComponent>,
private alertService: AlertMessageService,
private formBuilder: FormBuilder
private formBuilder: FormBuilder,
private translateService: TranslateService
) {
dialogRef.disableClose = true;//disable default close operation
this._currentDomain = data.domain;
......@@ -61,9 +64,13 @@ export class ManageMembersDialogComponent implements OnInit {
...data.member
};
this.currentFilter = "";
(async () => await this.updateFormTitle()) ();
}
get formTitle(){
return (!this._currentMember.memberId? "Invite":"Edit") + " " + this.membershipType + " member"
async updateFormTitle() {
this.formTitle = this._currentMember.memberId
? await lastValueFrom(this.translateService.get("manage.members.dialog.title.edit.mode", {membershipType: this.membershipType}))
: await lastValueFrom(this.translateService.get("manage.members.dialog.title.invite.mode", {membershipType: this.membershipType}));
}
get member(): MemberRo {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment