Skip to content

Commit

Permalink
feat(i18n): Finalize translations (#57)
Browse files Browse the repository at this point in the history
* createProjectDialog

* project dashboard

* edit project

* project list

* template variables 1

* template variable editor

* edit version component

* project version list

* project service

* user edit dialog

* user list

* me component

* dialogs

* .

* language switcher

* localized dates

* update dependencies

* review fixes

Co-authored-by: Tom <[email protected]>
  • Loading branch information
philmtd and tom-schoener authored Aug 30, 2021
1 parent 214c9f6 commit f8c1a92
Show file tree
Hide file tree
Showing 39 changed files with 2,355 additions and 1,949 deletions.
3,290 changes: 1,599 additions & 1,691 deletions frontend/package-lock.json

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,50 @@
},
"private": true,
"dependencies": {
"@angular/animations": "12.0.3",
"@angular/cdk": "12.0.3",
"@angular/common": "12.0.3",
"@angular/compiler": "12.0.3",
"@angular/core": "12.0.3",
"@angular/animations": "12.2.3",
"@angular/cdk": "12.2.3",
"@angular/common": "12.2.3",
"@angular/compiler": "12.2.3",
"@angular/core": "12.2.3",
"@angular/flex-layout": "12.0.0-beta.34",
"@angular/forms": "12.0.3",
"@angular/localize": "12.0.3",
"@angular/material": "12.0.3",
"@angular/platform-browser": "12.0.3",
"@angular/platform-browser-dynamic": "12.0.3",
"@angular/router": "12.0.3",
"@angular/forms": "12.2.3",
"@angular/localize": "12.2.3",
"@angular/material": "12.2.3",
"@angular/platform-browser": "12.2.3",
"@angular/platform-browser-dynamic": "12.2.3",
"@angular/router": "12.2.3",
"@mdi/svg": "5.9.55",
"@ngx-translate/core": "13.0.0",
"@ngx-translate/http-loader": "6.0.0",
"@ngxs/logger-plugin": "3.7.2",
"@ngxs/storage-plugin": "3.7.2",
"@ngxs/store": "3.7.2",
"core-js": "3.13.1",
"date-fns": "2.22.1",
"hash-it": "5.0.0",
"core-js": "3.16.3",
"date-fns": "2.23.0",
"hash-it": "5.0.2",
"lodash": "4.17.21",
"messageformat": "2.3.0",
"ngx-mat-select-search": "3.3.0",
"ngx-monaco-editor": "9.0.0",
"ngx-translate-messageformat-compiler": "4.9.0",
"ngx-translate-messageformat-compiler": "4.10.0",
"rxjs": "6.6.7",
"tslib": "2.2.0",
"tslib": "2.3.1",
"typescript-logging": "1.0.0",
"web-animations-js": "2.3.2",
"zone.js": "0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "12.0.3",
"@angular/cli": "12.0.3",
"@angular/compiler-cli": "12.0.3",
"@angular/language-service": "12.0.3",
"@angular-devkit/build-angular": "12.2.3",
"@angular/cli": "12.2.3",
"@angular/compiler-cli": "12.2.3",
"@angular/language-service": "12.2.3",
"@ngxs/devtools-plugin": "3.7.2",
"@types/jasmine": "3.7.6",
"@types/jasminewd2": "2.0.9",
"@types/lodash": "4.14.170",
"@types/node": "15.12.0",
"codelyzer": "^6.0.0",
"gzipper": "4.3.0",
"codelyzer": "^6.0.2",
"gzipper": "5.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.3.3",
Expand Down
19 changes: 14 additions & 5 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ import {
} from "./configuration/configuration";
import {MainComponent} from "./views/main/main.component";
import {ExpandableMenuComponent} from "./components/expandable-menu/expandable-menu.component";
import {NgxsModule} from "@ngxs/store";
import {NgxsModule, Store} from "@ngxs/store";
import {environment} from "../environments/environment.prod";
import {NgxsStoragePluginModule} from "@ngxs/storage-plugin";
import {NgxsReduxDevtoolsPluginModule} from "@ngxs/devtools-plugin";
Expand All @@ -115,6 +115,8 @@ import {HelmRegistryListComponent} from "./registries/helm/list/helm-registry-li
import {HelmRegistryEditDialogComponent} from "./registries/helm/edit-dialog/helm-registry-edit-dialog.component";
import {DistinctObjectArrayPipe} from "./util/distinct-object-array.pipe";
import {FilterDeepPipe} from "./util/filter-deep.pipe";
import {I18nSwitcherComponent} from "./components/i18n-switcher/i18n-switcher.component";
import {I18nState} from "./store/i18n/i18n.state";

@NgModule({
declarations: [
Expand Down Expand Up @@ -172,7 +174,8 @@ import {FilterDeepPipe} from "./util/filter-deep.pipe";
HelmRegistryListComponent,
HelmRegistryEditDialogComponent,
DistinctObjectArrayPipe,
FilterDeepPipe
FilterDeepPipe,
I18nSwitcherComponent
],
imports: [
BrowserModule,
Expand Down Expand Up @@ -213,7 +216,7 @@ import {FilterDeepPipe} from "./util/filter-deep.pipe";
MatRadioModule,
NgxMatSelectSearchModule,
NgxsModule.forRoot(appStates, {developmentMode: !environment.production}),
NgxsStoragePluginModule.forRoot({key: [ThemingState]}),
NgxsStoragePluginModule.forRoot({key: [ThemingState, I18nState]}),
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxsLoggerPluginModule.forRoot(),
TranslateModule.forRoot({
Expand Down Expand Up @@ -262,9 +265,15 @@ import {FilterDeepPipe} from "./util/filter-deep.pipe";
bootstrap: [AppComponent]
})
export class AppModule {
constructor(translateService: TranslateService, matIconRegistry: MatIconRegistry, domSanitizer: DomSanitizer, rest: RestService, auth: AuthService, ws: WebSocketService) {
constructor(translateService: TranslateService,
matIconRegistry: MatIconRegistry,
domSanitizer: DomSanitizer,
rest: RestService,
auth: AuthService,
ws: WebSocketService,
store: Store) {
configureSvgIcons(matIconRegistry, domSanitizer);
configureTranslations(translateService);
configureTranslations(translateService, store);

auth.isAuthenticated().subscribe(authenticated => {
if (authenticated) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<button mat-icon-button [matMenuTriggerFor]="modeMenu">
<mat-icon svgIcon="language"></mat-icon>
</button>
<mat-menu #modeMenu class="i18n-switcher-menu">
<button mat-menu-item *ngFor="let locale of locales" (click)="setLocale(locale.locale)" [class.active]="(currentLocale$ | async) === locale.locale">
<mat-icon [svgIcon]="((currentLocale$ | async) === locale.locale) ? 'mdi:radiobox-marked' : 'mdi:radiobox-blank'"></mat-icon>
<span>{{locale.label}}</span>
</button>
</mat-menu>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import "src/styles/mixins";

.active {
font-weight: 600;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@use '~@angular/material' as mat;
@import "src/styles/mixins";

@mixin i18n-switcher-component-theme($theme) {
$primary: map-get($theme, primary);
.i18n-switcher-menu {
.active {
font-weight: 600;
color: mat.get-color-from-palette($primary, 600);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {Component} from "@angular/core";
import {Select, Store} from "@ngxs/store";
import {Observable} from "rxjs";
import {I18nState, OnekoLocale, SetLocale} from "../../store/i18n/i18n.state";

@Component({
selector: 'on-i18n-switcher',
templateUrl: './i18n-switcher.component.html',
styleUrls: ['./i18n-switcher.component.scss']
})
export class I18nSwitcherComponent {

locales: Array<{ label: string, locale: OnekoLocale }>;

@Select(I18nState.locale) currentLocale$: Observable<OnekoLocale>;

constructor(private store: Store) {
this.locales = [
{
label: 'English',
locale: 'en'
}, {
label: 'Deutsch',
locale: 'de'
}
];
}

setLocale(locale: OnekoLocale) {
this.store.dispatch(new SetLocale(locale));
}
}
9 changes: 6 additions & 3 deletions frontend/src/app/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
} from '@angular/animations/browser';
import {TranslateService} from "@ngx-translate/core";
import {MatPaginatorIntl} from "@angular/material/paginator";
import {Store} from "@ngxs/store";
import {I18nState} from "../store/i18n/i18n.state";

export const configureSvgIcons = (iconRegistry: MatIconRegistry, domSanitizer: DomSanitizer) => {
iconRegistry.addSvgIconResolver((name, namespace) => {
Expand All @@ -27,10 +29,11 @@ export const provideAnimationDriverBasedOnUserPreferences = (): AnimationDriver
return prefersReducedMotion ? noop : driver;
};

export const configureTranslations = (translate: TranslateService) => {
export const configureTranslations = (translate: TranslateService, store: Store) => {
translate.setDefaultLang('en');
//translate.use(translate.getBrowserLang()); // todo: use once translation is finished
translate.use('en'); // todo: remove once translation is finished
store.select(I18nState.locale).subscribe(locale => {
translate.use(locale);
});
};

export const configureMatPaginatorI18n = (translate: TranslateService): MatPaginatorIntl => {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/app/navigation/navigation.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<mat-icon svgIcon="menu"></mat-icon>
</button>
<div fxFlex *ngIf="!isDesktop"></div>
<on-i18n-switcher></on-i18n-switcher>
<on-theme-switcher></on-theme-switcher>
<mat-divider [vertical]="true"></mat-divider>
<button mat-button routerLinkActive="active" [matMenuTriggerFor]="userMenu">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="project-edit-dialog create-dialog">
<h1 mat-dialog-title *ngIf="!showImport">Create a new project</h1>
<h1 mat-dialog-title *ngIf="showImport">Import a project</h1>
<h1 mat-dialog-title *ngIf="!showImport">{{ 'components.project.createProjectDialog.createNewProject' | translate }}</h1>
<h1 mat-dialog-title *ngIf="showImport">{{ 'components.project.createProjectDialog.importProject' | translate }}</h1>
<div mat-dialog-content>
<mat-horizontal-stepper [linear]="true" #stepper>
<ng-template matStepperIcon="import" let-index="index" *ngIf="showImport">
Expand All @@ -16,73 +16,70 @@ <h1 mat-dialog-title *ngIf="showImport">Import a project</h1>
{{index + 1}}
</ng-template>
<mat-step [stepControl]="projectImportFormGroup" *ngIf="showImport">
<ng-template matStepLabel>Import a project configuration file</ng-template>
<p>Import a project from a <i>.json</i> configuration file. You can configure the import in the next steps.</p>
<ng-template matStepLabel>{{ 'components.project.createProjectDialog.importProjectConfigurationFile' | translate }}</ng-template>
<div [innerHTML]="'components.project.createProjectDialog.importProjectDescription' | translate"></div>
<file-upload *ngIf="!projectExport"
[multiple]="false"
(filesCallback)="onProjectExportUpload($event)"
displayType="dnd"
accept=".json"
label="Upload project configuration"></file-upload>
[label]="'components.project.createProjectDialog.fileUploadLabel' | translate"></file-upload>
<div *ngIf="projectExport">
<p fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="12px">
<mat-icon svgIcon="check"></mat-icon>
<span>Upload successful!</span>
<span>{{ 'components.project.createProjectDialog.uploadSuccessful' | translate }}</span>
</p>
<p>The imported project has <b>{{projectExport.defaultConfigurationTemplates.length}}</b> configuration templates.</p>
<div [innerHTML]="'components.project.createProjectDialog.importCompleteDescription' | translate: {count: projectExport.defaultConfigurationTemplates.length}"></div>
</div>
<div>
<button mat-button matStepperNext>Next</button>
<button mat-button matStepperNext>{{ 'components.project.createProjectDialog.next' | translate }}</button>
</div>
</mat-step>
<mat-step [stepControl]="projectNameFormGroup">
<form [formGroup]="projectNameFormGroup">
<ng-template matStepLabel>Enter the new projects name</ng-template>
<p>Enter a meaningful name for your new project.</p>
<p>The name can be chosen arbitrarily but should be distinguishable from the names of yet existing projects.</p>
<ng-template matStepLabel>{{ 'components.project.createProjectDialog.enterProjectNameLabel' | translate }}</ng-template>
<div [innerHTML]="'components.project.createProjectDialog.enterProjectNameDescription' | translate"></div>
<mat-form-field>
<input matInput placeholder="Project name" required formControlName="nameCtrl" >
<input matInput [placeholder]="'components.project.createProjectDialog.projectName' | translate" required formControlName="nameCtrl" >
</mat-form-field>
<figure *ngIf="getCollidingProjectName()" class="warning">
<figcaption>Warning</figcaption>
<p>There is yet a project with the name {{getCollidingProjectName()}}.</p>
<figcaption>{{ 'general.warning' | translate }}</figcaption>
<p>{{ 'components.project.createProjectDialog.collidingProjectNameMessage' | translate: {name: getCollidingProjectName()} }}</p>
</figure>
<div>
<button mat-button matStepperPrevious *ngIf="showImport">Back</button>
<button mat-button matStepperNext>Next</button>
<button mat-button matStepperPrevious *ngIf="showImport">{{'components.project.createProjectDialog.back' | translate}}</button>
<button mat-button matStepperNext>{{ 'components.project.createProjectDialog.next' | translate }}</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="dockerRegistryFormGroup">
<form [formGroup]="dockerRegistryFormGroup">
<ng-template matStepLabel>Select a docker registry</ng-template>
<p>All images for this project will be picked from the docker registry you select here.</p>
<ng-template matStepLabel>{{ 'components.project.createProjectDialog.selectDockerRegistry' | translate }}</ng-template>
<p>{{ 'components.project.createProjectDialog.selectDockerRegistryDescription' | translate }}</p>
<mat-form-field>
<mat-label>Docker registry</mat-label>
<mat-label>{{ 'components.project.createProjectDialog.dockerRegistry' | translate }}</mat-label>
<mat-select required formControlName="registryUuidCtrl">
<mat-option *ngFor="let dockerRegistry of dockerRegistries" [value]="dockerRegistry.uuid">
{{ dockerRegistry.name }}
</mat-option>
</mat-select>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
<button mat-button matStepperPrevious>{{'components.project.createProjectDialog.back' | translate}}</button>
<button mat-button matStepperNext>{{ 'components.project.createProjectDialog.next' | translate }}</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="imageNameFormGroup">
<form [formGroup]="imageNameFormGroup">
<ng-template matStepLabel>Enter the new projects image name</ng-template>
<p>Type in the name of the docker image. This must match the image name as present on the docker registry.</p>
<p>We totally would like to offer you a list of image names to select from, but the docker API for retrieving these is a bit picky in terms of permissions.</p>
<p><span>Until we fix this, you have to type this on your own.</span><mat-icon svgIcon="mdi:emoticon-sad"></mat-icon></p>
<ng-template matStepLabel>{{ 'components.project.createProjectDialog.enterProjectImageName' | translate }}</ng-template>
<p>{{ 'components.project.createProjectDialog.enterProjectImageNameDescription' | translate }}</p>
<mat-form-field>
<input matInput placeholder="Image name" required formControlName="imageNameCtrl" >
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button [disabled]="!imageNameFormGroup.valid" (click)="finish()">Done</button>
<button mat-button matStepperPrevious>{{'components.project.createProjectDialog.back' | translate}}</button>
<button mat-button [disabled]="!imageNameFormGroup.valid" (click)="finish()">{{ 'general.done' | translate }}</button>
</div>
</form>
</mat-step>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {Project} from '../project';
import {FileReaderService} from '../../form/upload/file-reader.service';
import {MatSnackBar} from '@angular/material/snack-bar';
import {ProjectExportDTO} from '../project-export';
import {TranslateService} from "@ngx-translate/core";

export interface CreateProjectDialogComponentData {
projects: Array<Project>;
Expand Down Expand Up @@ -36,7 +37,8 @@ export class CreateProjectDialogComponent implements OnInit {
@Inject(MAT_DIALOG_DATA) readonly data: CreateProjectDialogComponentData,
private readonly rest: RestService,
private readonly formBuilder: FormBuilder,
private readonly snackBar: MatSnackBar) {
private readonly snackBar: MatSnackBar,
private readonly translate: TranslateService) {
this.rest.docker().getAllDockerRegistries().subscribe(regs => this.dockerRegistries = regs);
this.yetExistingProjects = data.projects;
this.showImport = data.showImport;
Expand Down Expand Up @@ -88,7 +90,7 @@ export class CreateProjectDialogComponent implements OnInit {
const [file] = await new FileReaderService().readAll($event);

if (typeof file.content !== 'string') {
this.snackBar.open(`Could not upload file ${file.name}`, null, {
this.snackBar.open(this.translate.instant('components.project.createProjectDialog.couldNotUploadFile', {name: file.name}), null, {
duration: 1000
});
return;
Expand All @@ -100,7 +102,7 @@ export class CreateProjectDialogComponent implements OnInit {
this.projectExport = projectExport;
} catch (e) {
console.error('Error while parsing exported project', e);
this.snackBar.open(`Error while parsing exported project configuration`, null, {
this.snackBar.open(this.translate.instant('components.project.createProjectDialog.errorParsingConfiguration'), null, {
duration: 1000
});
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="project-dashboard" fxLayout="column">
<div class="project-selection" fxLayout="row" fxLayoutAlign="space-between center">
<h4>Projects</h4>
<h4>{{ 'components.project.projectDashboard.projects' | translate }}</h4>
<mat-form-field *ngIf="projects.length > 1">
<mat-select placeholder="Projects" multiple [(ngModel)]="currentlyShownProjects">
<mat-select [placeholder]="'components.project.projectDashboard.projects' | translate" multiple [(ngModel)]="currentlyShownProjects">
<mat-option *ngFor="let project of projects" [value]="project.uuid">{{project.name}}</mat-option>
</mat-select>
</mat-form-field>
Expand Down Expand Up @@ -50,9 +50,7 @@ <h4 mat-line>{{version.name}}</h4>
</div>
<mat-divider *ngIf="!lastVersion"></mat-divider>
</div>
<span mat-list-item *ngIf="getDeployedVersionsOfProject(project).length === 0">
<strong>{{project.name}}</strong> has no deployed versions.
</span>
<span mat-list-item *ngIf="getDeployedVersionsOfProject(project).length === 0" [innerHTML]="'components.project.projectDashboard.projectHasNoDeployedVersions' | translate: {name: project.name}"></span>
</ng-container>
</mat-list>
</div>
Expand Down
Loading

0 comments on commit f8c1a92

Please sign in to comment.