This commit is contained in:
parent
7260de8384
commit
58f6e6bde7
7
frontend/libs/shared/locale/README.md
Normal file
7
frontend/libs/shared/locale/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# locale
|
||||||
|
|
||||||
|
This library was generated with [Nx](https://nx.dev).
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `nx test locale` to execute the unit tests.
|
||||||
34
frontend/libs/shared/locale/eslint.config.mjs
Normal file
34
frontend/libs/shared/locale/eslint.config.mjs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import nx from '@nx/eslint-plugin';
|
||||||
|
import baseConfig from '../../../eslint.base.config.mjs';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
...baseConfig,
|
||||||
|
...nx.configs['flat/angular'],
|
||||||
|
...nx.configs['flat/angular-template'],
|
||||||
|
{
|
||||||
|
files: ['**/*.ts'],
|
||||||
|
rules: {
|
||||||
|
'@angular-eslint/directive-selector': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
type: 'attribute',
|
||||||
|
prefix: 'lib',
|
||||||
|
style: 'camelCase',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'@angular-eslint/component-selector': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
type: 'element',
|
||||||
|
prefix: 'lib',
|
||||||
|
style: 'kebab-case',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['**/*.html'],
|
||||||
|
// Override or add rules here
|
||||||
|
rules: {},
|
||||||
|
},
|
||||||
|
];
|
||||||
21
frontend/libs/shared/locale/jest.config.ts
Normal file
21
frontend/libs/shared/locale/jest.config.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export default {
|
||||||
|
displayName: 'locale',
|
||||||
|
preset: '../../../jest.preset.js',
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||||
|
coverageDirectory: '../../../coverage/libs/shared/locale',
|
||||||
|
transform: {
|
||||||
|
'^.+\\.(ts|mjs|js|html)$': [
|
||||||
|
'jest-preset-angular',
|
||||||
|
{
|
||||||
|
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||||
|
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
||||||
|
snapshotSerializers: [
|
||||||
|
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||||
|
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||||
|
'jest-preset-angular/build/serializers/html-comment',
|
||||||
|
],
|
||||||
|
};
|
||||||
20
frontend/libs/shared/locale/project.json
Normal file
20
frontend/libs/shared/locale/project.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "locale",
|
||||||
|
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"sourceRoot": "libs/shared/locale/src",
|
||||||
|
"prefix": "lib",
|
||||||
|
"projectType": "library",
|
||||||
|
"tags": [],
|
||||||
|
"targets": {
|
||||||
|
"test": {
|
||||||
|
"executor": "@nx/jest:jest",
|
||||||
|
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "libs/shared/locale/jest.config.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"executor": "@nx/eslint:lint"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
frontend/libs/shared/locale/src/index.ts
Normal file
4
frontend/libs/shared/locale/src/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export * from './lib/common.namespace';
|
||||||
|
export * from './lib/common.t';
|
||||||
|
export * from './lib/locale-shell.component';
|
||||||
|
export * from './lib/locale.routes';
|
||||||
17
frontend/libs/shared/locale/src/lib/common.namespace.ts
Normal file
17
frontend/libs/shared/locale/src/lib/common.namespace.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { createNamespace as createCoreNamespace } from '@mmstack/translate';
|
||||||
|
|
||||||
|
const ns = createCoreNamespace('common', {
|
||||||
|
yes: 'Yes',
|
||||||
|
no: 'No',
|
||||||
|
actions: {
|
||||||
|
start: 'Start',
|
||||||
|
stop: 'Stop',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const createNamespace = ns.createMergedNamespace;
|
||||||
|
export const createTranslation = ns.createTranslation;
|
||||||
|
export default ns.translation;
|
||||||
|
|
||||||
|
export type CommonLocale = typeof ns.translation;
|
||||||
|
|
||||||
10
frontend/libs/shared/locale/src/lib/common.sl.ts
Normal file
10
frontend/libs/shared/locale/src/lib/common.sl.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { createTranslation } from './common.namespace';
|
||||||
|
|
||||||
|
export default createTranslation('sl', {
|
||||||
|
yes: 'Da',
|
||||||
|
no: 'Ne',
|
||||||
|
actions: {
|
||||||
|
start: 'Začni',
|
||||||
|
stop: 'Ustavi',
|
||||||
|
},
|
||||||
|
});
|
||||||
12
frontend/libs/shared/locale/src/lib/common.t.ts
Normal file
12
frontend/libs/shared/locale/src/lib/common.t.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { registerNamespace } from '@mmstack/translate';
|
||||||
|
|
||||||
|
const r = registerNamespace(
|
||||||
|
() => import('./common.namespace').then((m) => m.default),
|
||||||
|
{
|
||||||
|
sl: () => import('./common.sl').then((m) => m.default),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const injectCommonT = r.injectNamespaceT;
|
||||||
|
export const resolveCommonTranslations = r.resolveNamespaceTranslation;
|
||||||
|
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'frontend-locale-shell',
|
||||||
|
imports: [RouterOutlet],
|
||||||
|
template: `<router-outlet />`,
|
||||||
|
})
|
||||||
|
export class LocaleShellComponent {}
|
||||||
|
|
||||||
27
frontend/libs/shared/locale/src/lib/locale.routes.ts
Normal file
27
frontend/libs/shared/locale/src/lib/locale.routes.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Route } from '@angular/router';
|
||||||
|
import { resolveContainersTranslations } from '@frontend/web/containers';
|
||||||
|
|
||||||
|
export const LOCALE_ROUTE: Route[] = [
|
||||||
|
{
|
||||||
|
path: 'containers',
|
||||||
|
loadComponent: () =>
|
||||||
|
import('@frontend/web/containers').then(
|
||||||
|
(m) => m.ContainersComponentShell
|
||||||
|
),
|
||||||
|
resolve: {
|
||||||
|
resolveContainersTranslations,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'container',
|
||||||
|
loadComponent: () =>
|
||||||
|
import('@frontend/web/container').then(
|
||||||
|
(m) => m.ContainerDetailsComponent
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '**',
|
||||||
|
redirectTo: 'containers',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
6
frontend/libs/shared/locale/src/test-setup.ts
Normal file
6
frontend/libs/shared/locale/src/test-setup.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
|
||||||
|
|
||||||
|
setupZoneTestEnv({
|
||||||
|
errorOnUnknownElements: true,
|
||||||
|
errorOnUnknownProperties: true,
|
||||||
|
});
|
||||||
28
frontend/libs/shared/locale/tsconfig.json
Normal file
28
frontend/libs/shared/locale/tsconfig.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2022",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"files": [],
|
||||||
|
"include": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.lib.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.spec.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extends": "../../../tsconfig.base.json",
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
"strictInjectionParameters": true,
|
||||||
|
"strictInputAccessModifiers": true,
|
||||||
|
"strictTemplates": true
|
||||||
|
}
|
||||||
|
}
|
||||||
17
frontend/libs/shared/locale/tsconfig.lib.json
Normal file
17
frontend/libs/shared/locale/tsconfig.lib.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../../dist/out-tsc",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/test-setup.ts",
|
||||||
|
"jest.config.ts",
|
||||||
|
"src/**/*.test.ts"
|
||||||
|
],
|
||||||
|
"include": ["src/**/*.ts"]
|
||||||
|
}
|
||||||
16
frontend/libs/shared/locale/tsconfig.spec.json
Normal file
16
frontend/libs/shared/locale/tsconfig.spec.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../../dist/out-tsc",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es2016",
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"files": ["src/test-setup.ts"],
|
||||||
|
"include": [
|
||||||
|
"jest.config.ts",
|
||||||
|
"src/**/*.test.ts",
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -10,7 +10,7 @@ import { ThemeToggleService } from '@frontend/shared/theme-toggle';
|
|||||||
imports: [MatToolbarModule, MatIcon, MatButtonModule],
|
imports: [MatToolbarModule, MatIcon, MatButtonModule],
|
||||||
template: `
|
template: `
|
||||||
<mat-toolbar class="navbar">
|
<mat-toolbar class="navbar">
|
||||||
<div (click)="goToHome()">
|
<div (click)="goToHome()" class="title">
|
||||||
<mat-icon>view_carousel</mat-icon>
|
<mat-icon>view_carousel</mat-icon>
|
||||||
<span>Docker Containers</span>
|
<span>Docker Containers</span>
|
||||||
</div>
|
</div>
|
||||||
@ -26,6 +26,12 @@ import { ThemeToggleService } from '@frontend/shared/theme-toggle';
|
|||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
background-color: var(--mat-accent-500);
|
background-color: var(--mat-accent-500);
|
||||||
color: var(--mat-accent-contrast-500);
|
color: var(--mat-accent-contrast-500);
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
export * from './lib/containers-shell.component';
|
export * from './lib/containers-shell.component';
|
||||||
|
export * from './lib/translations/containers.t';
|
||||||
|
|||||||
@ -2,12 +2,18 @@ import { Component, inject, OnInit } from '@angular/core';
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { WsService } from '@frontend/shared/ws';
|
import { WsService } from '@frontend/shared/ws';
|
||||||
import { ContainerCardComponent } from './container-card.component';
|
import { ContainerCardComponent } from './container-card.component';
|
||||||
|
import { ContainersTranslatePipe } from './translations/translation.pipe';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'frontend-containers',
|
selector: 'frontend-containers',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [ContainerCardComponent],
|
imports: [ContainerCardComponent, ContainersTranslatePipe],
|
||||||
template: `
|
template: `
|
||||||
|
<p>
|
||||||
|
{{
|
||||||
|
'containers.containersFound' | translate: { count: containers().length }
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
<div class="content-container">
|
<div class="content-container">
|
||||||
@for (container of containers(); track container.id) {
|
@for (container of containers(); track container.id) {
|
||||||
<frontend-container-card
|
<frontend-container-card
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { createQuoteTranslation } from './containers.namespace';
|
||||||
|
|
||||||
|
export default createQuoteTranslation('sl', {
|
||||||
|
containersFound:
|
||||||
|
'{count, plural, =1 { {count} kontejner} =2 { {count} kontejnerja} other { {count} kontejnerjev}}',
|
||||||
|
});
|
||||||
|
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { createNamespace } from '@frontend/shared/locale';
|
||||||
|
|
||||||
|
const ns = createNamespace('containers', {
|
||||||
|
containersFound:
|
||||||
|
'{count, plural, =1 {# {count} container } other {# containers }}',
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ns.translation;
|
||||||
|
|
||||||
|
export type ContainersLocale = (typeof ns)['translation'];
|
||||||
|
|
||||||
|
export const createQuoteTranslation = ns.createTranslation;
|
||||||
|
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { registerNamespace } from '@mmstack/translate';
|
||||||
|
|
||||||
|
const r = registerNamespace(
|
||||||
|
() => import('./containers.namespace').then((m) => m.default),
|
||||||
|
{
|
||||||
|
sl: () => import('./containers-sl.translation').then((m) => m.default),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const injectContainersT = r.injectNamespaceT;
|
||||||
|
export const resolveContainersTranslations = r.resolveNamespaceTranslation;
|
||||||
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { Directive } from '@angular/core';
|
||||||
|
import { BaseTranslateDirective } from '@mmstack/translate';
|
||||||
|
import { type ContainersLocale } from './containers.namespace';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[translate]',
|
||||||
|
})
|
||||||
|
export class ContainersTranslateDirective<
|
||||||
|
TInput extends string,
|
||||||
|
> extends BaseTranslateDirective<TInput, ContainersLocale> {}
|
||||||
|
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { Pipe } from '@angular/core';
|
||||||
|
import { BaseTranslatePipe } from '@mmstack/translate';
|
||||||
|
import { type ContainersLocale } from './containers.namespace';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'translate',
|
||||||
|
})
|
||||||
|
export class ContainersTranslatePipe extends BaseTranslatePipe<ContainersLocale> {}
|
||||||
|
|
||||||
100
frontend/package-lock.json
generated
100
frontend/package-lock.json
generated
@ -18,10 +18,12 @@
|
|||||||
"@angular/platform-browser": "20.0.2",
|
"@angular/platform-browser": "20.0.2",
|
||||||
"@angular/platform-browser-dynamic": "20.0.2",
|
"@angular/platform-browser-dynamic": "20.0.2",
|
||||||
"@angular/router": "20.0.2",
|
"@angular/router": "20.0.2",
|
||||||
|
"@formatjs/intl": "^3.1.6",
|
||||||
"@mmstack/form-material": "19.2.2",
|
"@mmstack/form-material": "19.2.2",
|
||||||
"@mmstack/primitives": "19.2.3",
|
"@mmstack/primitives": "19.2.3",
|
||||||
"@mmstack/resource": "19.2.0",
|
"@mmstack/resource": "19.2.0",
|
||||||
"@mmstack/router-core": "^19.3.0",
|
"@mmstack/router-core": "^19.3.0",
|
||||||
|
"@mmstack/translate": "^19.2.8",
|
||||||
"rxjs": "7.8.2",
|
"rxjs": "7.8.2",
|
||||||
"zone.js": "0.15.1"
|
"zone.js": "0.15.1"
|
||||||
},
|
},
|
||||||
@ -5612,6 +5614,78 @@
|
|||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@formatjs/ecma402-abstract": {
|
||||||
|
"version": "2.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz",
|
||||||
|
"integrity": "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/fast-memoize": "2.2.7",
|
||||||
|
"@formatjs/intl-localematcher": "0.6.1",
|
||||||
|
"decimal.js": "^10.4.3",
|
||||||
|
"tslib": "^2.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/fast-memoize": {
|
||||||
|
"version": "2.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz",
|
||||||
|
"integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/icu-messageformat-parser": {
|
||||||
|
"version": "2.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.2.tgz",
|
||||||
|
"integrity": "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.3.4",
|
||||||
|
"@formatjs/icu-skeleton-parser": "1.8.14",
|
||||||
|
"tslib": "^2.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/icu-skeleton-parser": {
|
||||||
|
"version": "1.8.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.14.tgz",
|
||||||
|
"integrity": "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.3.4",
|
||||||
|
"tslib": "^2.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/intl": {
|
||||||
|
"version": "3.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-3.1.6.tgz",
|
||||||
|
"integrity": "sha512-tDkXnA4qpIFcDWac8CyVJq6oW8DR7W44QDUBsfXWIIJD/FYYen0QoH46W7XsVMFfPOVKkvbufjboZrrWbEfmww==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.3.4",
|
||||||
|
"@formatjs/fast-memoize": "2.2.7",
|
||||||
|
"@formatjs/icu-messageformat-parser": "2.11.2",
|
||||||
|
"intl-messageformat": "10.7.16",
|
||||||
|
"tslib": "^2.8.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@formatjs/intl-localematcher": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@humanfs/core": {
|
"node_modules/@humanfs/core": {
|
||||||
"version": "0.19.1",
|
"version": "0.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||||
@ -7043,6 +7117,19 @@
|
|||||||
"rxjs": "~7.8.2"
|
"rxjs": "~7.8.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@mmstack/translate": {
|
||||||
|
"version": "19.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mmstack/translate/-/translate-19.2.8.tgz",
|
||||||
|
"integrity": "sha512-YsKjX6kLqSXyjKywdZKZDfTtcpvYWYTJzyfUJM66tprAcGoEI3Nsc97bh1k7lXKkbCRqgwuiEVa2gBjWjcF7/Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/core": "~19.2.3",
|
||||||
|
"@formatjs/intl": "~3.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@modern-js/node-bundle-require": {
|
"node_modules/@modern-js/node-bundle-require": {
|
||||||
"version": "2.67.6",
|
"version": "2.67.6",
|
||||||
"resolved": "https://registry.npmjs.org/@modern-js/node-bundle-require/-/node-bundle-require-2.67.6.tgz",
|
"resolved": "https://registry.npmjs.org/@modern-js/node-bundle-require/-/node-bundle-require-2.67.6.tgz",
|
||||||
@ -14215,7 +14302,6 @@
|
|||||||
"version": "10.5.0",
|
"version": "10.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
|
||||||
"integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
|
"integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/dedent": {
|
"node_modules/dedent": {
|
||||||
@ -17117,6 +17203,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/intl-messageformat": {
|
||||||
|
"version": "10.7.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz",
|
||||||
|
"integrity": "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"@formatjs/ecma402-abstract": "2.3.4",
|
||||||
|
"@formatjs/fast-memoize": "2.2.7",
|
||||||
|
"@formatjs/icu-messageformat-parser": "2.11.2",
|
||||||
|
"tslib": "^2.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ip-address": {
|
"node_modules/ip-address": {
|
||||||
"version": "9.0.5",
|
"version": "9.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
|
||||||
|
|||||||
@ -18,10 +18,12 @@
|
|||||||
"@angular/platform-browser": "20.0.2",
|
"@angular/platform-browser": "20.0.2",
|
||||||
"@angular/platform-browser-dynamic": "20.0.2",
|
"@angular/platform-browser-dynamic": "20.0.2",
|
||||||
"@angular/router": "20.0.2",
|
"@angular/router": "20.0.2",
|
||||||
|
"@formatjs/intl": "^3.1.6",
|
||||||
"@mmstack/form-material": "19.2.2",
|
"@mmstack/form-material": "19.2.2",
|
||||||
"@mmstack/primitives": "19.2.3",
|
"@mmstack/primitives": "19.2.3",
|
||||||
"@mmstack/resource": "19.2.0",
|
"@mmstack/resource": "19.2.0",
|
||||||
"@mmstack/router-core": "^19.3.0",
|
"@mmstack/router-core": "^19.3.0",
|
||||||
|
"@mmstack/translate": "^19.2.8",
|
||||||
"rxjs": "7.8.2",
|
"rxjs": "7.8.2",
|
||||||
"zone.js": "0.15.1"
|
"zone.js": "0.15.1"
|
||||||
},
|
},
|
||||||
|
|||||||
0
frontend/public/env.js
Normal file
0
frontend/public/env.js
Normal file
@ -3,6 +3,7 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
|||||||
import { provideRouter, withPreloading } from '@angular/router';
|
import { provideRouter, withPreloading } from '@angular/router';
|
||||||
import { ENVIRONMENT } from '@frontend/shared/environment';
|
import { ENVIRONMENT } from '@frontend/shared/environment';
|
||||||
import { PreloadStrategy } from '@mmstack/router-core';
|
import { PreloadStrategy } from '@mmstack/router-core';
|
||||||
|
import { provideIntlConfig } from '@mmstack/translate';
|
||||||
import { environment } from '../environments/environment';
|
import { environment } from '../environments/environment';
|
||||||
import { appRoutes } from './app.routes';
|
import { appRoutes } from './app.routes';
|
||||||
|
|
||||||
@ -11,6 +12,9 @@ export const appConfig: ApplicationConfig = {
|
|||||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||||
provideHttpClient(),
|
provideHttpClient(),
|
||||||
provideRouter(appRoutes, withPreloading(PreloadStrategy)),
|
provideRouter(appRoutes, withPreloading(PreloadStrategy)),
|
||||||
|
provideIntlConfig({
|
||||||
|
defaultLocale: 'en',
|
||||||
|
}),
|
||||||
{ provide: ENVIRONMENT, useValue: environment },
|
{ provide: ENVIRONMENT, useValue: environment },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,22 +1,52 @@
|
|||||||
import { Route } from '@angular/router';
|
import { ActivatedRouteSnapshot, Route } from '@angular/router';
|
||||||
|
|
||||||
|
import { inject, Injectable, LOCALE_ID } from '@angular/core';
|
||||||
|
import {
|
||||||
|
LocaleShellComponent,
|
||||||
|
resolveCommonTranslations,
|
||||||
|
} from '@frontend/shared/locale';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class LocaleStore {
|
||||||
|
locale = 'en';
|
||||||
|
}
|
||||||
|
|
||||||
export const appRoutes: Route[] = [
|
export const appRoutes: Route[] = [
|
||||||
{
|
{
|
||||||
path: 'containers',
|
path: ':locale',
|
||||||
loadComponent: () =>
|
component: LocaleShellComponent,
|
||||||
import('@frontend/web/containers').then(
|
resolve: {
|
||||||
(m) => m.ContainersComponentShell
|
localeId: (route: ActivatedRouteSnapshot) => {
|
||||||
),
|
const store = inject(LocaleStore);
|
||||||
|
const locale = route.params['locale'] || 'en';
|
||||||
|
|
||||||
|
store.locale = locale;
|
||||||
|
|
||||||
|
return locale;
|
||||||
|
},
|
||||||
|
common: resolveCommonTranslations,
|
||||||
|
},
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
useFactory: (store: LocaleStore) => {
|
||||||
|
return store.locale;
|
||||||
|
},
|
||||||
|
deps: [LocaleStore],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
loadChildren: () =>
|
||||||
|
import('@frontend/shared/locale').then((m) => m.LOCALE_ROUTE),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'container',
|
path: '',
|
||||||
loadComponent: () =>
|
redirectTo: 'en',
|
||||||
import('@frontend/web/container').then(
|
pathMatch: 'full',
|
||||||
(m) => m.ContainerDetailsComponent
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
redirectTo: 'containers',
|
redirectTo: 'en',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@frontend/shared/environment": ["libs/shared/environment/src/index.ts"],
|
"@frontend/shared/environment": ["libs/shared/environment/src/index.ts"],
|
||||||
|
"@frontend/shared/locale": ["libs/shared/locale/src/index.ts"],
|
||||||
"@frontend/shared/navbar": ["libs/shared/navbar/src/index.ts"],
|
"@frontend/shared/navbar": ["libs/shared/navbar/src/index.ts"],
|
||||||
"@frontend/shared/theme-toggle": [
|
"@frontend/shared/theme-toggle": [
|
||||||
"libs/shared/theme-toggle/src/index.ts"
|
"libs/shared/theme-toggle/src/index.ts"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user