// => this will output Hello, otter friend!
@@ -221,7 +221,7 @@ export class SimpleHeaderPresModule {}
-
+
```
@@ -233,7 +233,7 @@ As a result "**hello bold**" will be printed inside the span element.
-{{ "someBagsAdded" | translate:{bags: 5} }} // => will output "You have added 5 bags"
+{{ "someBagsAdded" | o3rTranslate:{bags: 5} }} // => will output "You have added 5 bags"
```
@@ -485,7 +485,7 @@ import {MESSAGE_FORMAT_CONFIG} from 'ngx-translate-messageformat-compiler';
```typescript
// component html template
...
- {{translations.nbOfErrors | translate: {count: countMessages} }}
+ {{translations.nbOfErrors | o3rTranslate: {count: countMessages} }}
...
```
The value of _translations.nbOfErrors_ is the translation key 'o3r-list-inline-messages-pres.nbOfErrors'. The next step translates the key passing some parameters to translate pipe.
@@ -508,9 +508,9 @@ Sometimes you may want to display a different resource based on some property va
```typescript
// in component html
- - {{ translations.people | translate: { gender: 'female', how: 'influential' } }}
- - {{ translations.people | translate: { gender: 'male', how: 'funny' } }}
- - {{ translations.people | translate: { how: 'affectionate' } }}
+ - {{ translations.people | o3rTranslate: { gender: 'female', how: 'influential' } }}
+ - {{ translations.people | o3rTranslate: { gender: 'male', how: 'funny' } }}
+ - {{ translations.people | o3rTranslate: { how: 'affectionate' } }}
```
Note again that _translations.people_ matches _global.people_ key
diff --git a/packages/@o3r/components/migration.json b/packages/@o3r/components/migration.json
new file mode 100644
index 0000000000..62836c1d0a
--- /dev/null
+++ b/packages/@o3r/components/migration.json
@@ -0,0 +1,10 @@
+{
+ "$schema": "https://raw.githubusercontent.com/angular/angular-cli/master/packages/angular_devkit/schematics/collection-schema.json",
+ "schematics": {
+ "migration-v10_0": {
+ "version": "10.0.0-alpha.0",
+ "description": "Updates of the Otter Library to v10.0.*",
+ "factory": "./schematics/ng-update/v10-0/index#updateV10_0"
+ }
+ }
+}
diff --git a/packages/@o3r/components/package.json b/packages/@o3r/components/package.json
index 88385096c3..37b07e80d7 100644
--- a/packages/@o3r/components/package.json
+++ b/packages/@o3r/components/package.json
@@ -17,7 +17,7 @@
"nx": "nx",
"ng": "yarn nx",
"copy:schemas": "yarn cpy 'schemas/*.json' dist/schemas",
- "prepare:build:builders": "yarn cpy 'builders/**/*.json' dist/builders && yarn cpy 'schematics/**/*.json' 'schematics/**/templates/**' dist/schematics && yarn cpy '{builders,collection}.json' dist && yarn copy:schemas",
+ "prepare:build:builders": "yarn cpy 'builders/**/*.json' dist/builders && yarn cpy 'schematics/**/*.json' 'schematics/**/templates/**' dist/schematics && yarn cpy '{builders,collection,migration}.json' dist && yarn copy:schemas",
"prepare:publish": "prepare-publish ./dist",
"prepare:compile": "cp-package-json",
"build:builders": "tsc -b tsconfig.builders.json --pretty && yarn generate-cjs-manifest",
diff --git a/packages/@o3r/components/schematics/ng-update/v10-0/index.spec.ts b/packages/@o3r/components/schematics/ng-update/v10-0/index.spec.ts
new file mode 100644
index 0000000000..6d0f1acddd
--- /dev/null
+++ b/packages/@o3r/components/schematics/ng-update/v10-0/index.spec.ts
@@ -0,0 +1,77 @@
+import { Tree } from '@angular-devkit/schematics';
+import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
+import * as fs from 'node:fs';
+import * as path from 'node:path';
+
+const migrationPath = path.join(__dirname, '..', '..', '..', 'migration.json');
+
+
+describe('Update v10', () => {
+ describe('Update pipes', () => {
+ let initialTree: Tree;
+ let runner: SchematicTestRunner;
+ beforeEach(() => {
+ initialTree = Tree.empty();
+ initialTree.create('angular.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', 'angular.mocks.json')));
+ initialTree.create('package.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', 'package.mocks.json')));
+ initialTree.create('.eslintrc.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', '__dot__eslintrc.mocks.json')));
+ initialTree.create('src/components/example.template.html', '{{ 120 | duration }}');
+ runner = new SchematicTestRunner('schematics', migrationPath);
+ });
+
+ it('should replace the pipe with standalone component', async () => {
+ initialTree.create('src/components/example.component.ts', `
+ import { Component } from '@angular/core';
+ import { O3rComponent } from '@o3r/core';
+ import { DurationPipeModule } from '@o3r/components';
+
+ @O3rComponent({ componentType: 'Component' })
+ @Component({
+ selector: 'o3r-example',
+ standalone: true,
+ imports: [DurationPipeModule],
+ templateUrl: './example.template.html'
+ })
+ export class ExampleComponent {
+ }
+ `);
+ const tree = await runner.runSchematic('migration-v10_0', {}, initialTree);
+ expect(tree.readText('src/components/example.component.ts')).toMatch('O3rDurationPipe');
+ expect(tree.readText('src/components/example.component.ts')).not.toMatch('DurationPipeModule');
+ expect(tree.readText('src/components/example.template.html')).toMatch('| o3rDuration');
+ expect(tree.readText('src/components/example.template.html')).not.toMatch('| duration');
+ });
+
+ it('should replace the pipe with module based component', async () => {
+ initialTree.create('src/components/example.component.ts', `
+ import { Component } from '@angular/core';
+ import { O3rComponent } from '@o3r/core';
+
+ @O3rComponent({ componentType: 'Component' })
+ @Component({
+ selector: 'o3r-example',
+ templateUrl: './example.template.html'
+ })
+ export class ExampleComponent {
+ }
+ `);
+ initialTree.create('src/components/example.module.ts', `
+ import { NgModule } from '@angular/core';
+ import { DurationPipeModule } from '@o3r/components';
+ import { ExampleComponent } from './example.component';
+
+ @NgModule({
+ imports: [DurationPipeModule],
+ declarations: [ExampleComponent],
+ exports: [ExampleComponent]
+ })
+ export class ExampleModule {}
+ `);
+ const tree = await runner.runSchematic('migration-v10_0', {}, initialTree);
+ expect(tree.readText('src/components/example.module.ts')).toMatch('O3rDurationPipe');
+ expect(tree.readText('src/components/example.module.ts')).not.toMatch('DurationPipeModule');
+ expect(tree.readText('src/components/example.template.html')).toMatch('| o3rDuration');
+ expect(tree.readText('src/components/example.template.html')).not.toMatch('| duration');
+ });
+ });
+});
diff --git a/packages/@o3r/components/schematics/ng-update/v10-0/index.ts b/packages/@o3r/components/schematics/ng-update/v10-0/index.ts
new file mode 100644
index 0000000000..f788854bbc
--- /dev/null
+++ b/packages/@o3r/components/schematics/ng-update/v10-0/index.ts
@@ -0,0 +1,53 @@
+/* eslint-disable camelcase, @typescript-eslint/naming-convention */
+import { chain, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
+import { createSchematicWithMetricsIfInstalled, PipeReplacementInfo, updatePipes } from '@o3r/schematics';
+
+const pipeReplacementInfo: PipeReplacementInfo = {
+ capitalize: {
+ new: {
+ name: 'o3rCapitalize',
+ import: 'O3rCapitalizePipe'
+ },
+ import: 'CapitalizePipeModule'
+ },
+ duration: {
+ new: {
+ name: 'o3rDuration',
+ import: 'O3rDurationPipe'
+ },
+ import: 'DurationPipeModule'
+ },
+ keepWhiteSpace: {
+ new: {
+ name: 'o3rKeepWhiteSpace',
+ import: 'O3rKeepWhiteSpacePipe'
+ },
+ import: 'KeepWhiteSpacePipeModule'
+ },
+ replaceWithBold: {
+ new: {
+ name: 'o3rReplaceWithBold',
+ import: 'O3rReplaceWithBoldPipe'
+ },
+ import: 'ReplaceWithBoldPipeModule'
+ }
+};
+
+/**
+ * Update of Otter library V10.0
+ */
+function updateV10_0Fn(): Rule {
+ return (tree: Tree, context: SchematicContext) => {
+
+ const updateRules: Rule[] = [
+ updatePipes(pipeReplacementInfo)
+ ];
+
+ return chain(updateRules)(tree, context);
+ };
+}
+
+/**
+ * Update of Otter library V10.0
+ */
+export const updateV10_0 = createSchematicWithMetricsIfInstalled(updateV10_0Fn);
diff --git a/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.module.ts b/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.module.ts
index ca93c01925..dbd908f6e5 100644
--- a/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.module.ts
+++ b/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.module.ts
@@ -1,6 +1,9 @@
import {NgModule} from '@angular/core';
import {CapitalizePipe} from './capitalize.pipe';
+/**
+ * @deprecated please use O3rCapitalizePipe, will be removed in v12.
+ */
@NgModule({
declarations: [CapitalizePipe],
exports: [CapitalizePipe]
diff --git a/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.spec.ts b/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.spec.ts
index 686668c147..a76a026e16 100644
--- a/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.spec.ts
+++ b/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.spec.ts
@@ -1,22 +1,28 @@
-import {CapitalizePipe} from './capitalize.pipe';
+import {CapitalizePipe, O3rCapitalizePipe} from './capitalize.pipe';
describe('CapitalizePipe', () => {
- const pipe = new CapitalizePipe();
+ const pipe = new O3rCapitalizePipe();
+ const deprecatedPipe = new CapitalizePipe();
it('transforms "abc" to "Abc"', () => {
expect(pipe.transform('abc')).toBe('Abc');
+ expect(deprecatedPipe.transform('abc')).toBe('Abc');
});
it('transforms "abc def" to "Abc def"', () => {
expect(pipe.transform('abc def')).toBe('Abc def');
+ expect(deprecatedPipe.transform('abc def')).toBe('Abc def');
});
it('ignores whitespace', () => {
expect(pipe.transform(' ')).toBe(' ');
+ expect(deprecatedPipe.transform(' ')).toBe(' ');
});
it('does not break on empty values', () => {
expect(pipe.transform()).toBe(undefined);
+ expect(deprecatedPipe.transform()).toBe(undefined);
expect(pipe.transform(null)).toBe(null);
+ expect(deprecatedPipe.transform(null)).toBe(null);
});
});
diff --git a/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.ts b/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.ts
index dcdd68a180..43bbc5b3cc 100644
--- a/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.ts
+++ b/packages/@o3r/components/src/tools/pipes/capitalize/capitalize.pipe.ts
@@ -1,10 +1,17 @@
import {Pipe, PipeTransform} from '@angular/core';
-@Pipe({name: 'capitalize'})
-export class CapitalizePipe implements PipeTransform {
+@Pipe({name: 'o3rCapitalize', standalone: true})
+export class O3rCapitalizePipe implements PipeTransform {
public transform(value?: any) {
const val: string | undefined = value && value.toString && value.toString();
const firstLetter: string | undefined = val && val.charAt(0);
return firstLetter ? firstLetter.toUpperCase() + val!.slice(1) : value;
}
}
+
+/**
+ * @deprecated please use O3rCapitalizePipe, will be removed in v12.
+ */
+@Pipe({name: 'capitalize'})
+export class CapitalizePipe extends O3rCapitalizePipe implements PipeTransform {}
+
diff --git a/packages/@o3r/components/src/tools/pipes/duration/duration.module.ts b/packages/@o3r/components/src/tools/pipes/duration/duration.module.ts
index 066c45b9c5..9fba645d13 100644
--- a/packages/@o3r/components/src/tools/pipes/duration/duration.module.ts
+++ b/packages/@o3r/components/src/tools/pipes/duration/duration.module.ts
@@ -1,6 +1,9 @@
import {NgModule} from '@angular/core';
import {DurationPipe} from './duration.pipe';
+/**
+ * @deprecated please use O3rDurationPipe, will be removed in v12.
+ */
@NgModule({
declarations: [DurationPipe],
exports: [DurationPipe]
diff --git a/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.spec.ts b/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.spec.ts
index 22136c39dd..f8f65476c9 100644
--- a/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.spec.ts
+++ b/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.spec.ts
@@ -1,54 +1,67 @@
-import {DurationPipe} from './duration.pipe';
+import {DurationPipe, O3rDurationPipe} from './duration.pipe';
describe('DurationPipe', () => {
- const pipe = new DurationPipe();
+ const pipe = new O3rDurationPipe();
+ const deprecatedPipe = new DurationPipe();
it('transforms 120s to 0:02', () => {
expect(pipe.transform(120)).toBe('0:02');
+ expect(deprecatedPipe.transform(120)).toBe('0:02');
});
it('transforms 100s to 0:01', () => {
expect(pipe.transform(100)).toBe('0:01');
+ expect(deprecatedPipe.transform(100)).toBe('0:01');
});
it('transforms 3660 seconds to "1:01"', () => {
expect(pipe.transform(3660)).toBe('1:01');
+ expect(deprecatedPipe.transform(3660)).toBe('1:01');
});
it('transforms 90000s to "25:00" (duration exceeds 24 hours)', () => {
expect(pipe.transform(90000)).toBe('25:00');
+ expect(deprecatedPipe.transform(90000)).toBe('25:00');
});
it('transforms 360000s to "100:00" (hours are 3 digits long)', () => {
expect(pipe.transform(360000)).toBe('100:00');
+ expect(deprecatedPipe.transform(360000)).toBe('100:00');
});
it('transforms 120s to 0h02m', () => {
expect(pipe.transform(120, '{h}h{mm}m')).toBe('0h02m');
+ expect(deprecatedPipe.transform(120, '{h}h{mm}m')).toBe('0h02m');
});
it('transforms 120s to 00H02M', () => {
expect(pipe.transform(120, '{hh}H{mm}M')).toBe('00H02M');
+ expect(deprecatedPipe.transform(120, '{hh}H{mm}M')).toBe('00H02M');
});
it('transforms 3660s to 1h01', () => {
expect(pipe.transform(3660, '{h}h{mm}')).toBe('1h01');
+ expect(deprecatedPipe.transform(3660, '{h}h{mm}')).toBe('1h01');
});
it('transforms 86399s to 0d23h59m', () => {
expect(pipe.transform(86399, '{d}d{h}h{mm}m')).toBe('0d23h59m');
+ expect(deprecatedPipe.transform(86399, '{d}d{h}h{mm}m')).toBe('0d23h59m');
});
it('transforms 86399s to 0d86399s', () => {
expect(pipe.transform(86399, '{d}d{s}s')).toBe('0d86399s');
+ expect(deprecatedPipe.transform(86399, '{d}d{s}s')).toBe('0d86399s');
});
it('transforms 93675s to an object "{"d": 1, "h": 2, "m": 1, "s": 15}"', () => {
expect(pipe.transform(93675, '{"d": {d}, "h": {h}, "m": {m}, "s": {s}}')).toBe('{"d": 1, "h": 2, "m": 1, "s": 15}');
+ expect(deprecatedPipe.transform(93675, '{"d": {d}, "h": {h}, "m": {m}, "s": {s}}')).toBe('{"d": 1, "h": 2, "m": 1, "s": 15}');
});
it('returns pattern when regex not respected', () => {
expect(pipe.transform(1234, 'hh:mm')).toBe('hh:mm');
+ expect(deprecatedPipe.transform(1234, 'hh:mm')).toBe('hh:mm');
});
it('should work for custom unit times', () => {
@@ -61,6 +74,15 @@ describe('DurationPipe', () => {
divider: 25
}
])).toBe('57:1');
+ expect(deprecatedPipe.transform(5725, '{t}:{k}', [
+ {
+ formatCharacter: 't',
+ divider: 100
+ }, {
+ formatCharacter: 'k',
+ divider: 25
+ }
+ ])).toBe('57:1');
});
it('should work for unit times that are not present in the pattern', () => {
@@ -77,5 +99,18 @@ describe('DurationPipe', () => {
modulo: 25
}
])).toBe('57:0');
+ expect(deprecatedPipe.transform(5725, '{t}:{k}', [
+ {
+ formatCharacter: 't',
+ divider: 100
+ }, {
+ formatCharacter: 'o',
+ divider: 25
+ }, {
+ formatCharacter: 'k',
+ divider: 1,
+ modulo: 25
+ }
+ ])).toBe('57:0');
});
});
diff --git a/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.ts b/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.ts
index 78f6ff7b8b..4a38cb8d72 100644
--- a/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.ts
+++ b/packages/@o3r/components/src/tools/pipes/duration/duration.pipe.ts
@@ -17,9 +17,8 @@ function padNum(num: number, digits: number) {
/**
* Converts a duration in seconds into the HH:mm format
*/
-@Pipe({name: 'duration'})
-export class DurationPipe implements PipeTransform {
-
+@Pipe({name: 'o3rDuration', standalone: true})
+export class O3rDurationPipe implements PipeTransform {
/**
* @param value the value in seconds
* @param pattern the desired output format.
@@ -65,3 +64,10 @@ export class DurationPipe implements PipeTransform {
}
}
+
+/**
+ * Converts a duration in seconds into the HH:mm format
+ * @deprecated please use O3rDurationPipe, will be removed in v12.
+ */
+@Pipe({name: 'duration'})
+export class DurationPipe extends O3rDurationPipe implements PipeTransform {}
diff --git a/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.module.ts b/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.module.ts
index 0c22dc3d0c..9b1b33becb 100644
--- a/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.module.ts
+++ b/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.module.ts
@@ -1,6 +1,9 @@
import {NgModule} from '@angular/core';
import {KeepWhiteSpacePipe} from './keep-white-space.pipe';
+/**
+ * @deprecated please use O3rKeepWhiteSpacePipe, will be removed in v12.
+ */
@NgModule({
declarations: [KeepWhiteSpacePipe],
exports: [KeepWhiteSpacePipe]
diff --git a/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.spec.ts b/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.spec.ts
index 795edb7d57..d85fe33221 100644
--- a/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.spec.ts
+++ b/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.spec.ts
@@ -1,31 +1,26 @@
-import {KeepWhiteSpacePipe} from './keep-white-space.pipe';
+import {KeepWhiteSpacePipe, O3rKeepWhiteSpacePipe} from './keep-white-space.pipe';
describe('Keep white space pipe', () => {
- let pipe: KeepWhiteSpacePipe;
+ let pipe: O3rKeepWhiteSpacePipe;
+ let deprecatedPipe: KeepWhiteSpacePipe;
beforeEach(() => {
- pipe = new KeepWhiteSpacePipe();
+ pipe = new O3rKeepWhiteSpacePipe();
+ deprecatedPipe = new KeepWhiteSpacePipe();
});
it('does nothing when no white spaces', () => {
-
- const transformedString = pipe.transform('Guatemala');
-
- expect(transformedString).toEqual('Guatemala');
+ expect(pipe.transform('Guatemala')).toEqual('Guatemala');
+ expect(deprecatedPipe.transform('Guatemala')).toEqual('Guatemala');
});
it('should work with space inside the word', () => {
-
- const transformedString = pipe.transform('French Guiana');
-
- expect(transformedString).toEqual('French Guiana');
+ expect(pipe.transform('French Guiana')).toEqual('French Guiana');
+ expect(deprecatedPipe.transform('French Guiana')).toEqual('French Guiana');
});
it('should do nothing when empty string', () => {
-
- const transformedString = pipe.transform('');
-
- expect(transformedString).toEqual('');
+ expect(pipe.transform('')).toEqual('');
+ expect(deprecatedPipe.transform('')).toEqual('');
});
-
});
diff --git a/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.ts b/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.ts
index 13282fea78..cd4fbc5834 100644
--- a/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.ts
+++ b/packages/@o3r/components/src/tools/pipes/keep-white-space/keep-white-space.pipe.ts
@@ -1,11 +1,18 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
- name: 'keepWhiteSpace',
- pure: true
+ name: 'o3rKeepWhiteSpace'
})
-export class KeepWhiteSpacePipe implements PipeTransform {
+export class O3rKeepWhiteSpacePipe implements PipeTransform {
public transform(value: string): string {
return value.replace(/\s/g, ' ');
}
}
+
+/**
+ * @deprecated please use O3rKeepWhiteSpacePipe, will be removed in v12.
+ */
+@Pipe({
+ name: 'keepWhiteSpace'
+})
+export class KeepWhiteSpacePipe extends O3rKeepWhiteSpacePipe implements PipeTransform {}
diff --git a/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.module.ts b/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.module.ts
index 3ba559425b..2d5743ad33 100644
--- a/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.module.ts
+++ b/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.module.ts
@@ -1,6 +1,9 @@
import {NgModule} from '@angular/core';
import {ReplaceWithBoldPipe} from './replace-with-bold.pipe';
+/**
+ * @deprecated please use O3rReplaceWithBoldPipe, will be removed in v12.
+ */
@NgModule({
declarations: [ReplaceWithBoldPipe],
exports: [ReplaceWithBoldPipe]
diff --git a/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.spec.ts b/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.spec.ts
index 7ee79c7825..7f517a89b2 100644
--- a/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.spec.ts
+++ b/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.spec.ts
@@ -1,59 +1,47 @@
-import {ReplaceWithBoldPipe} from './replace-with-bold.pipe';
+import {O3rReplaceWithBoldPipe, ReplaceWithBoldPipe} from './replace-with-bold.pipe';
describe('Replace with bold pipe', () => {
- let pipe: ReplaceWithBoldPipe;
+ let pipe: O3rReplaceWithBoldPipe;
+ let deprecatedPipe: ReplaceWithBoldPipe;
beforeEach(() => {
- pipe = new ReplaceWithBoldPipe();
+ pipe = new O3rReplaceWithBoldPipe();
+ deprecatedPipe = new ReplaceWithBoldPipe();
});
it('search if the input match the label and change it to bold', () => {
-
- const transformedString = pipe.transform('Guatemala', 'te');
-
- expect(transformedString).toEqual('Gua
temala');
+ expect(pipe.transform('Guatemala', 'te')).toEqual('Gua
temala');
+ expect(deprecatedPipe.transform('Guatemala', 'te')).toEqual('Gua
temala');
});
it('does nothing when no match', () => {
-
- const transformedString = pipe.transform('Guatemala', 'sp');
-
- expect(transformedString).toEqual('Guatemala');
+ expect(pipe.transform('Guatemala', 'sp')).toEqual('Guatemala');
+ expect(deprecatedPipe.transform('Guatemala', 'sp')).toEqual('Guatemala');
});
it('should work with space inside the word', () => {
-
- const transformedString = pipe.transform('French Guiana', 'g');
-
- expect(transformedString).toEqual('French
Guiana');
+ expect(pipe.transform('French Guiana', 'g')).toEqual('French
Guiana');
+ expect(deprecatedPipe.transform('French Guiana', 'g')).toEqual('French
Guiana');
});
it('search input match - special character test', () => {
-
- const transformedString = pipe.transform('Finland (HEL)', '(H');
-
- expect(transformedString).toEqual('Finland
(HEL)');
+ expect(pipe.transform('Finland (HEL)', '(H')).toEqual('Finland
(HEL)');
+ expect(deprecatedPipe.transform('Finland (HEL)', '(H')).toEqual('Finland
(HEL)');
});
it('should ignore white spaces at the beginning', () => {
-
- const transformedString = pipe.transform('Finland (HEL)', ' (H');
-
- expect(transformedString).toEqual('Finland
(HEL)');
+ expect(pipe.transform('Finland (HEL)', ' (H')).toEqual('Finland
(HEL)');
+ expect(deprecatedPipe.transform('Finland (HEL)', ' (H')).toEqual('Finland
(HEL)');
});
it('should ignore white spaces', () => {
-
- const transformedString = pipe.transform('Finland (HEL)', ' (H ');
-
- expect(transformedString).toEqual('Finland
(HEL)');
+ expect(pipe.transform('Finland (HEL)', ' (H ')).toEqual('Finland
(HEL)');
+ expect(deprecatedPipe.transform('Finland (HEL)', ' (H ')).toEqual('Finland
(HEL)');
});
it('should not ignore white spaces in the middle (no matches)', () => {
-
- const transformedString = pipe.transform('Finland (HEL)', ' (H E');
-
- expect(transformedString).toEqual('Finland (HEL)');
+ expect(pipe.transform('Finland (HEL)', ' (H E')).toEqual('Finland (HEL)');
+ expect(deprecatedPipe.transform('Finland (HEL)', ' (H E')).toEqual('Finland (HEL)');
});
});
diff --git a/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.ts b/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.ts
index e599b6a679..eb6c385e01 100644
--- a/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.ts
+++ b/packages/@o3r/components/src/tools/pipes/replace-with-bold/replace-with-bold.pipe.ts
@@ -1,20 +1,30 @@
import {Pipe, PipeTransform} from '@angular/core';
+const escapeRegExp = (str: string) => str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
+
@Pipe({
- name: 'replaceWithBold',
- pure: true
+ name: 'o3rReplaceWithBold',
+ standalone: true
})
-export class ReplaceWithBoldPipe implements PipeTransform {
+export class O3rReplaceWithBoldPipe implements PipeTransform {
public transform(value: string, inputText: string): string {
if (inputText) {
- const regexp = new RegExp(this.escapeRegExp(inputText.trim()), 'gi');
+ const regexp = new RegExp(escapeRegExp(inputText.trim()), 'gi');
return value.replace(regexp, (match) => `
${match}`);
} else {
return value;
}
}
+}
+/**
+ * @deprecated please use O3rReplaceWithBoldPipe, will be removed in v12.
+ */
+@Pipe({
+ name: 'replaceWithBold'
+})
+export class ReplaceWithBoldPipe extends O3rReplaceWithBoldPipe implements PipeTransform {
public escapeRegExp(str: string) {
- return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
+ return escapeRegExp(str);
}
}
diff --git a/packages/@o3r/dynamic-content/README.md b/packages/@o3r/dynamic-content/README.md
index 344e0d8085..9edb15e5b0 100644
--- a/packages/@o3r/dynamic-content/README.md
+++ b/packages/@o3r/dynamic-content/README.md
@@ -37,8 +37,8 @@ The module provides two things:
A pipe to be used in your component templates:
```html
-
or
-
+
or
+
```
and a service to be used in your component classes, for example:
@@ -151,7 +151,7 @@ It also looks for overrides in the `AssetPathOverrideStore`, so it will return t
## AssetPathOverrideStore
-A dedicated store is available in case you want to override any media path.
+A dedicated store is available in case you want to override any media path.
This store contains a mapping between the current file path and the one that should be used instead.
This override ONLY WORKS for media resources.
diff --git a/packages/@o3r/dynamic-content/migration.json b/packages/@o3r/dynamic-content/migration.json
new file mode 100644
index 0000000000..62836c1d0a
--- /dev/null
+++ b/packages/@o3r/dynamic-content/migration.json
@@ -0,0 +1,10 @@
+{
+ "$schema": "https://raw.githubusercontent.com/angular/angular-cli/master/packages/angular_devkit/schematics/collection-schema.json",
+ "schematics": {
+ "migration-v10_0": {
+ "version": "10.0.0-alpha.0",
+ "description": "Updates of the Otter Library to v10.0.*",
+ "factory": "./schematics/ng-update/v10-0/index#updateV10_0"
+ }
+ }
+}
diff --git a/packages/@o3r/dynamic-content/package.json b/packages/@o3r/dynamic-content/package.json
index cabdfb5bce..c0e31e1211 100644
--- a/packages/@o3r/dynamic-content/package.json
+++ b/packages/@o3r/dynamic-content/package.json
@@ -22,7 +22,7 @@
"build": "yarn nx build dynamic-content",
"build:fixtures:jest": "tsc -b tsconfig.fixture.jest.json --pretty",
"build:fixtures:jasmine": "tsc -b tsconfig.fixture.jasmine.json --pretty",
- "prepare:build:builders": "yarn cpy 'schematics/**/*.json' dist/schematics && yarn cpy 'collection.json' dist && yarn cpy 'schemas/*.json' dist/schemas",
+ "prepare:build:builders": "yarn cpy 'schematics/**/*.json' dist/schematics && yarn cpy '{collection,migration}.json' dist && yarn cpy 'schemas/*.json' dist/schemas",
"prepare:publish": "prepare-publish ./dist"
},
"peerDependencies": {
diff --git a/packages/@o3r/dynamic-content/schematics/ng-update/v10-0/index.spec.ts b/packages/@o3r/dynamic-content/schematics/ng-update/v10-0/index.spec.ts
new file mode 100644
index 0000000000..da2a704f9b
--- /dev/null
+++ b/packages/@o3r/dynamic-content/schematics/ng-update/v10-0/index.spec.ts
@@ -0,0 +1,75 @@
+import { Tree } from '@angular-devkit/schematics';
+import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
+import * as fs from 'node:fs';
+import * as path from 'node:path';
+
+const migrationPath = path.join(__dirname, '..', '..', '..', 'migration.json');
+
+
+describe('Update v10', () => {
+ describe('Update pipes', () => {
+ let initialTree: Tree;
+ let runner: SchematicTestRunner;
+ beforeEach(() => {
+ initialTree = Tree.empty();
+ initialTree.create('angular.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', 'angular.mocks.json')));
+ initialTree.create('package.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', 'package.mocks.json')));
+ initialTree.create('.eslintrc.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', '__dot__eslintrc.mocks.json')));
+ initialTree.create('src/components/example.template.html', '{{ "asset.png" | dynamicContent }}');
+ runner = new SchematicTestRunner('schematics', migrationPath);
+ });
+
+ it('should replace the pipe with standalone component', async () => {
+ initialTree.create('src/components/example.component.ts', `
+ import { Component } from '@angular/core';
+ import { O3rComponent } from '@o3r/core';
+ import { DynamicContentModule } from '@o3r/dynamic-content';
+
+ @O3rComponent({ componentType: 'Component' })
+ @Component({
+ selector: 'o3r-example',
+ standalone: true,
+ imports: [DynamicContentModule],
+ templateUrl: './example.template.html'
+ })
+ export class ExampleComponent {
+ }
+ `);
+ const tree = await runner.runSchematic('migration-v10_0', {}, initialTree);
+ expect(tree.readText('src/components/example.component.ts')).toMatch('DynamicContentModule');
+ expect(tree.readText('src/components/example.template.html')).toMatch('| o3rDynamicContent');
+ expect(tree.readText('src/components/example.template.html')).not.toMatch('| dynamicContent');
+ });
+
+ it('should replace the pipe with module based component', async () => {
+ initialTree.create('src/components/example.component.ts', `
+ import { Component } from '@angular/core';
+ import { O3rComponent } from '@o3r/core';
+
+ @O3rComponent({ componentType: 'Component' })
+ @Component({
+ selector: 'o3r-example',
+ templateUrl: './example.template.html'
+ })
+ export class ExampleComponent {
+ }
+ `);
+ initialTree.create('src/components/example.module.ts', `
+ import { NgModule } from '@angular/core';
+ import { DynamicContentModule } from '@o3r/dynamic-content';
+ import { ExampleComponent } from './example.component';
+
+ @NgModule({
+ imports: [DynamicContentModule],
+ declarations: [ExampleComponent],
+ exports: [ExampleComponent]
+ })
+ export class ExampleModule {}
+ `);
+ const tree = await runner.runSchematic('migration-v10_0', {}, initialTree);
+ expect(tree.readText('src/components/example.module.ts')).toMatch('DynamicContentModule');
+ expect(tree.readText('src/components/example.template.html')).toMatch('| o3rDynamicContent');
+ expect(tree.readText('src/components/example.template.html')).not.toMatch('| dynamicContent');
+ });
+ });
+});
diff --git a/packages/@o3r/dynamic-content/schematics/ng-update/v10-0/index.ts b/packages/@o3r/dynamic-content/schematics/ng-update/v10-0/index.ts
new file mode 100644
index 0000000000..2b2d43b18d
--- /dev/null
+++ b/packages/@o3r/dynamic-content/schematics/ng-update/v10-0/index.ts
@@ -0,0 +1,31 @@
+/* eslint-disable camelcase, @typescript-eslint/naming-convention */
+import { chain, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
+import { createSchematicWithMetricsIfInstalled, PipeReplacementInfo, updatePipes } from '@o3r/schematics';
+
+const pipeReplacementInfo: PipeReplacementInfo = {
+ dynamicContent: {
+ new: {
+ name: 'o3rDynamicContent'
+ },
+ import: 'DynamicContentModule'
+ }
+};
+
+/**
+ * Update of Otter library V10.0
+ */
+function updateV10_0Fn(): Rule {
+ return (tree: Tree, context: SchematicContext) => {
+
+ const updateRules: Rule[] = [
+ updatePipes(pipeReplacementInfo)
+ ];
+
+ return chain(updateRules)(tree, context);
+ };
+}
+
+/**
+ * Update of Otter library V10.0
+ */
+export const updateV10_0 = createSchematicWithMetricsIfInstalled(updateV10_0Fn);
diff --git a/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.module.ts b/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.module.ts
index f97eacd55a..d6db2687e0 100644
--- a/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.module.ts
+++ b/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.module.ts
@@ -1,5 +1,5 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
-import { DynamicContentPipe } from './dynamic-content.pipe';
+import { DynamicContentPipe, O3rDynamicContentPipe } from './dynamic-content.pipe';
import { DynamicContentService } from './dynamic-content.service';
import { CMS_ASSETS_PATH_TOKEN, DYNAMIC_CONTENT_BASE_PATH_TOKEN } from './dynamic-content.token';
@@ -19,7 +19,7 @@ export function getCmsAssets() {
}
@NgModule({
- declarations: [DynamicContentPipe],
+ declarations: [DynamicContentPipe, O3rDynamicContentPipe],
providers: [
{
provide: DYNAMIC_CONTENT_BASE_PATH_TOKEN,
@@ -31,7 +31,7 @@ export function getCmsAssets() {
},
DynamicContentService
],
- exports: [DynamicContentPipe]
+ exports: [DynamicContentPipe, O3rDynamicContentPipe]
})
/**
* DynamicContent module
diff --git a/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.spec.ts b/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.spec.ts
index b310204a55..785ba162af 100644
--- a/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.spec.ts
+++ b/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.spec.ts
@@ -3,7 +3,7 @@ import { ComponentFixture, getTestBed, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { InterfaceOf } from '@o3r/core';
import { of } from 'rxjs';
-import { DynamicContentPipe } from './dynamic-content.pipe';
+import { DynamicContentPipe, O3rDynamicContentPipe } from './dynamic-content.pipe';
import { DynamicContentService } from './dynamic-content.service';
@@ -15,7 +15,7 @@ const serviceMock: InterfaceOf
= {
@Component({
// eslint-disable-next-line @typescript-eslint/quotes
- template: `{{'assets.png' | dynamicContent}}`
+ template: `{{'assets.png' | o3rDynamicContent}}{{'deprecatedPipe.png' | dynamicContent}}`
})
class HostTestComponent {}
@@ -28,7 +28,7 @@ describe('DynamicContentPipe', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
- declarations: [DynamicContentPipe, HostTestComponent],
+ declarations: [O3rDynamicContentPipe, DynamicContentPipe, HostTestComponent],
providers: [{provide: DynamicContentService, useValue: serviceMock}]
}).compileComponents();
@@ -39,6 +39,7 @@ describe('DynamicContentPipe', () => {
fixture.detectChanges();
expect(serviceMock.getMediaPathStream).toHaveBeenCalledWith('assets.png');
+ expect(serviceMock.getMediaPathStream).toHaveBeenCalledWith('deprecatedPipe.png');
});
});
diff --git a/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.ts b/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.ts
index 0bed59e4a0..89ab7c5881 100644
--- a/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.ts
+++ b/packages/@o3r/dynamic-content/src/services/dynamic-content/dynamic-content.pipe.ts
@@ -2,18 +2,18 @@ import { ChangeDetectorRef, OnDestroy, Pipe, PipeTransform } from '@angular/core
import { Subscription } from 'rxjs';
import { DynamicContentService } from './dynamic-content.service';
-@Pipe({name: 'dynamicContent', pure: false})
-export class DynamicContentPipe implements PipeTransform, OnDestroy {
+@Pipe({name: 'o3rDynamicContent', pure: false})
+export class O3rDynamicContentPipe implements PipeTransform, OnDestroy {
/** Last query value */
- private lastQuery?: string;
+ protected lastQuery?: string;
/** Subscription to retrieve media path */
- private onMediaPathChange?: Subscription;
+ protected onMediaPathChange?: Subscription;
/** Path to the media */
- private mediaPath = '';
+ protected mediaPath = '';
- constructor(private readonly service: DynamicContentService, private readonly cd: ChangeDetectorRef) {}
+ constructor(protected readonly service: DynamicContentService, protected readonly cd: ChangeDetectorRef) {}
/** @inheritDoc */
public transform(query?: string) {
@@ -38,3 +38,7 @@ export class DynamicContentPipe implements PipeTransform, OnDestroy {
}
}
}
+
+/** @deprecated please use O3rDynamicContentPipe, will be removed in v12. */
+@Pipe({name: 'dynamicContent', pure: false})
+export class DynamicContentPipe extends O3rDynamicContentPipe implements PipeTransform {}
diff --git a/packages/@o3r/dynamic-content/src/services/request-parameters/request-parameters.spec.ts b/packages/@o3r/dynamic-content/src/services/request-parameters/request-parameters.spec.ts
index 748e8b5b11..a5b3aed391 100644
--- a/packages/@o3r/dynamic-content/src/services/request-parameters/request-parameters.spec.ts
+++ b/packages/@o3r/dynamic-content/src/services/request-parameters/request-parameters.spec.ts
@@ -303,7 +303,7 @@ describe('RequestParametersService', () => {
imports: [RequestParametersModule.forRoot(getConfiguration)]
}).compileComponents();
- service = TestBed.get(RequestParametersService);
+ service = TestBed.inject(RequestParametersService);
});
afterEach(() => {
@@ -505,7 +505,7 @@ describe('RequestParametersService', () => {
imports: [RequestParametersModule.forRoot(getConfiguration)]
}).compileComponents();
- service = TestBed.get(RequestParametersService);
+ service = TestBed.inject(RequestParametersService);
});
it('should be defined', () => {
diff --git a/packages/@o3r/dynamic-content/testing/mocks/__dot__eslintrc.mocks.json b/packages/@o3r/dynamic-content/testing/mocks/__dot__eslintrc.mocks.json
new file mode 100644
index 0000000000..85e3a25942
--- /dev/null
+++ b/packages/@o3r/dynamic-content/testing/mocks/__dot__eslintrc.mocks.json
@@ -0,0 +1,5 @@
+{
+ "rules": {
+ "ban": [true, "fit", "fdescribe"]
+ }
+}
diff --git a/packages/@o3r/dynamic-content/testing/mocks/angular.mocks.json b/packages/@o3r/dynamic-content/testing/mocks/angular.mocks.json
new file mode 100644
index 0000000000..c34167f9cc
--- /dev/null
+++ b/packages/@o3r/dynamic-content/testing/mocks/angular.mocks.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://raw.githubusercontent.com/angular/angular-cli/master/packages/angular/cli/lib/config/workspace-schema.json",
+ "version": 1,
+ "newProjectRoot": ".",
+ "projects": {
+ "test-project": {
+ "projectType": "application",
+ "root": ".",
+ "sourceRoot": "./src",
+ "prefix": "tst",
+ "architect": {
+ "build": {
+ "builder": "",
+ "options": {
+ "tsConfig": "tsconfig.json"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/@o3r/dynamic-content/testing/mocks/package.mocks.json b/packages/@o3r/dynamic-content/testing/mocks/package.mocks.json
new file mode 100644
index 0000000000..c64b320ebd
--- /dev/null
+++ b/packages/@o3r/dynamic-content/testing/mocks/package.mocks.json
@@ -0,0 +1,5 @@
+{
+ "name": "test-project",
+ "version": "0.0.0",
+ "description": "Test project"
+}
diff --git a/packages/@o3r/dynamic-content/tsconfig.spec.json b/packages/@o3r/dynamic-content/tsconfig.spec.json
index 01fea8bf1e..7e4c561a63 100644
--- a/packages/@o3r/dynamic-content/tsconfig.spec.json
+++ b/packages/@o3r/dynamic-content/tsconfig.spec.json
@@ -6,7 +6,7 @@
"rootDir": ".",
},
"include": [
- "./src/**/*.spec.ts"
+ "./**/*.spec.ts"
],
"exclude": [],
"references": [
diff --git a/packages/@o3r/localization/README.md b/packages/@o3r/localization/README.md
index 89cbda455d..2234212c56 100644
--- a/packages/@o3r/localization/README.md
+++ b/packages/@o3r/localization/README.md
@@ -201,7 +201,7 @@ export class SimpleHeaderPresModule {}
-{{ "o3r-simple-header-pres.motto" | translate }} // => this will output Let's shape the future of travel
+{{ "o3r-simple-header-pres.motto" | o3rTranslate }} // => this will output Let's shape the future of travel
// => this will output Hello, otter friend!
@@ -214,7 +214,7 @@ export class SimpleHeaderPresModule {}
-
+
```
@@ -226,7 +226,7 @@ As a result "**hello bold**" will be printed inside the span element.
-{{ "someBagsAdded" | translate:{bags: 5} }} // => will output "You have added 5 bags"
+{{ "someBagsAdded" | o3rTranslate:{bags: 5} }} // => will output "You have added 5 bags"
```
@@ -479,7 +479,7 @@ import {MESSAGE_FORMAT_CONFIG} from 'ngx-translate-messageformat-compiler';
```typescript
// component html template
...
- {{translations.nbOfErrors | translate: {count: countMessages} }}
+ {{translations.nbOfErrors | o3rTranslate: {count: countMessages} }}
...
```
@@ -504,9 +504,9 @@ Sometimes you may want to display a different resource based on some property va
```typescript
// in component html
- - {{ translations.people | translate: { gender: 'female', how: 'influential' } }}
- - {{ translations.people | translate: { gender: 'male', how: 'funny' } }}
- - {{ translations.people | translate: { how: 'affectionate' } }}
+ - {{ translations.people | o3rTranslate: { gender: 'female', how: 'influential' } }}
+ - {{ translations.people | o3rTranslate: { gender: 'male', how: 'funny' } }}
+ - {{ translations.people | o3rTranslate: { how: 'affectionate' } }}
```
diff --git a/packages/@o3r/localization/migration.json b/packages/@o3r/localization/migration.json
new file mode 100644
index 0000000000..62836c1d0a
--- /dev/null
+++ b/packages/@o3r/localization/migration.json
@@ -0,0 +1,10 @@
+{
+ "$schema": "https://raw.githubusercontent.com/angular/angular-cli/master/packages/angular_devkit/schematics/collection-schema.json",
+ "schematics": {
+ "migration-v10_0": {
+ "version": "10.0.0-alpha.0",
+ "description": "Updates of the Otter Library to v10.0.*",
+ "factory": "./schematics/ng-update/v10-0/index#updateV10_0"
+ }
+ }
+}
diff --git a/packages/@o3r/localization/package.json b/packages/@o3r/localization/package.json
index 4ae3a04fa3..00d280697e 100644
--- a/packages/@o3r/localization/package.json
+++ b/packages/@o3r/localization/package.json
@@ -18,7 +18,7 @@
"ng": "yarn nx",
"copy:templates": "yarn cpy 'schematics/**/templates/**' dist/schematics",
"copy:schemas": "yarn cpy 'schemas/*.json' dist/schemas",
- "prepare:build:builders": "yarn cpy 'builders/**/*.json' dist/builders && yarn cpy '{builders,collection}.json' dist && yarn cpy 'schematics/**/*.json' dist/schematics && yarn copy:templates && yarn copy:schemas",
+ "prepare:build:builders": "yarn cpy 'builders/**/*.json' dist/builders && yarn cpy '{builders,collection,migration}.json' dist && yarn cpy 'schematics/**/*.json' dist/schematics && yarn copy:templates && yarn copy:schemas",
"prepare:compile": "cp-package-json",
"prepare:publish": "prepare-publish ./dist",
"build:builders": "tsc -b tsconfig.builders.json --pretty && yarn generate-cjs-manifest",
diff --git a/packages/@o3r/localization/schematics/add-localization-key/index.spec.ts b/packages/@o3r/localization/schematics/add-localization-key/index.spec.ts
index 4fdaa0910c..4c2ec8d69b 100644
--- a/packages/@o3r/localization/schematics/add-localization-key/index.spec.ts
+++ b/packages/@o3r/localization/schematics/add-localization-key/index.spec.ts
@@ -97,7 +97,7 @@ describe('Add Localization', () => {
}, initialTree);
const templateFileContent = tree.readText(templatePath);
- expect(templateFileContent).toBe('
{{ translations.dummyLoc1 | translate }}
');
+ expect(templateFileContent).toBe('
{{ translations.dummyLoc1 | o3rTranslate }}
');
const translationFileContent = tree.readText(translationPath);
expect(translationFileContent).toContain('dummyLoc1: string;');
diff --git a/packages/@o3r/localization/schematics/add-localization-key/index.ts b/packages/@o3r/localization/schematics/add-localization-key/index.ts
index 428775f164..8ac68fd747 100644
--- a/packages/@o3r/localization/schematics/add-localization-key/index.ts
+++ b/packages/@o3r/localization/schematics/add-localization-key/index.ts
@@ -227,7 +227,7 @@ export function ngAddLocalizationKeyFn(options: NgAddLocalizationKeySchematicsSc
if (templatePath) {
tree.overwrite(
templatePath,
- tree.readText(templatePath).replaceAll(options.value, `{{ translations.${properties.keyName} | translate }}`)
+ tree.readText(templatePath).replaceAll(options.value, `{{ translations.${properties.keyName} | o3rTranslate }}`)
);
}
};
diff --git a/packages/@o3r/localization/schematics/localization-to-component/index.spec.ts b/packages/@o3r/localization/schematics/localization-to-component/index.spec.ts
index ba4f56fd45..dc4bda6d4e 100644
--- a/packages/@o3r/localization/schematics/localization-to-component/index.spec.ts
+++ b/packages/@o3r/localization/schematics/localization-to-component/index.spec.ts
@@ -103,7 +103,7 @@ describe('Add Localization', () => {
expect(componentFileContent).toContain('@Localization(\'./test.localization.json\')');
const templateFileContent = tree.readText(templatePath);
- expect(templateFileContent).toContain('
Localization: {{ translations.dummyLoc1 | translate }}
');
+ expect(templateFileContent).toContain('
Localization: {{ translations.dummyLoc1 | o3rTranslate }}
');
const specFileContent = tree.readText(specPath);
expect(specFileContent).toContain('const localizationService = TestBed.inject(LocalizationService);');
diff --git a/packages/@o3r/localization/schematics/localization-to-component/index.ts b/packages/@o3r/localization/schematics/localization-to-component/index.ts
index f13d155057..ef349a8921 100644
--- a/packages/@o3r/localization/schematics/localization-to-component/index.ts
+++ b/packages/@o3r/localization/schematics/localization-to-component/index.ts
@@ -227,7 +227,7 @@ export function ngAddLocalizationFn(options: NgAddLocalizationSchematicsSchema):
tree.commitUpdate(
tree
.beginUpdate(templatePath)
- .insertLeft(0, '
Localization: {{ translations.dummyLoc1 | translate }}
\n')
+ .insertLeft(0, '
Localization: {{ translations.dummyLoc1 | o3rTranslate }}
\n')
);
}
diff --git a/packages/@o3r/localization/schematics/ng-update/v10-0/index.spec.ts b/packages/@o3r/localization/schematics/ng-update/v10-0/index.spec.ts
new file mode 100644
index 0000000000..72168d42c1
--- /dev/null
+++ b/packages/@o3r/localization/schematics/ng-update/v10-0/index.spec.ts
@@ -0,0 +1,75 @@
+import { Tree } from '@angular-devkit/schematics';
+import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
+import * as fs from 'node:fs';
+import * as path from 'node:path';
+
+const migrationPath = path.join(__dirname, '..', '..', '..', 'migration.json');
+
+
+describe('Update v10', () => {
+ describe('Update pipes', () => {
+ let initialTree: Tree;
+ let runner: SchematicTestRunner;
+ beforeEach(() => {
+ initialTree = Tree.empty();
+ initialTree.create('angular.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', 'angular.mocks.json')));
+ initialTree.create('package.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', 'package.mocks.json')));
+ initialTree.create('.eslintrc.json', fs.readFileSync(path.resolve(__dirname, '..', '..', '..', 'testing', 'mocks', '__dot__eslintrc.mocks.json')));
+ initialTree.create('src/components/example.template.html', '{{ "localization.key" | translate }}');
+ runner = new SchematicTestRunner('schematics', migrationPath);
+ });
+
+ it('should replace the pipe with standalone component', async () => {
+ initialTree.create('src/components/example.component.ts', `
+ import { Component } from '@angular/core';
+ import { O3rComponent } from '@o3r/core';
+ import { LocalizationModule } from '@o3r/localization';
+
+ @O3rComponent({ componentType: 'Component' })
+ @Component({
+ selector: 'o3r-example',
+ standalone: true,
+ imports: [LocalizationModule],
+ templateUrl: './example.template.html'
+ })
+ export class ExampleComponent {
+ }
+ `);
+ const tree = await runner.runSchematic('migration-v10_0', {}, initialTree);
+ expect(tree.readText('src/components/example.component.ts')).toMatch('LocalizationModule');
+ expect(tree.readText('src/components/example.template.html')).toMatch('| o3rTranslate');
+ expect(tree.readText('src/components/example.template.html')).not.toMatch('| translate');
+ });
+
+ it('should replace the pipe with module based component', async () => {
+ initialTree.create('src/components/example.component.ts', `
+ import { Component } from '@angular/core';
+ import { O3rComponent } from '@o3r/core';
+
+ @O3rComponent({ componentType: 'Component' })
+ @Component({
+ selector: 'o3r-example',
+ templateUrl: './example.template.html'
+ })
+ export class ExampleComponent {
+ }
+ `);
+ initialTree.create('src/components/example.module.ts', `
+ import { NgModule } from '@angular/core';
+ import { LocalizationModule } from '@o3r/localization';
+ import { ExampleComponent } from './example.component';
+
+ @NgModule({
+ imports: [LocalizationModule],
+ declarations: [ExampleComponent],
+ exports: [ExampleComponent]
+ })
+ export class ExampleModule {}
+ `);
+ const tree = await runner.runSchematic('migration-v10_0', {}, initialTree);
+ expect(tree.readText('src/components/example.module.ts')).toMatch('LocalizationModule');
+ expect(tree.readText('src/components/example.template.html')).toMatch('| o3rTranslate');
+ expect(tree.readText('src/components/example.template.html')).not.toMatch('| translate');
+ });
+ });
+});
diff --git a/packages/@o3r/localization/schematics/ng-update/v10-0/index.ts b/packages/@o3r/localization/schematics/ng-update/v10-0/index.ts
new file mode 100644
index 0000000000..87a0cc1721
--- /dev/null
+++ b/packages/@o3r/localization/schematics/ng-update/v10-0/index.ts
@@ -0,0 +1,31 @@
+/* eslint-disable camelcase, @typescript-eslint/naming-convention */
+import { chain, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
+import { createSchematicWithMetricsIfInstalled, PipeReplacementInfo, updatePipes } from '@o3r/schematics';
+
+const pipeReplacementInfo: PipeReplacementInfo = {
+ translate: {
+ new: {
+ name: 'o3rTranslate'
+ },
+ import: 'LocalizationModule'
+ }
+};
+
+/**
+ * Update of Otter library V10.0
+ */
+function updateV10_0Fn(): Rule {
+ return (tree: Tree, context: SchematicContext) => {
+
+ const updateRules: Rule[] = [
+ updatePipes(pipeReplacementInfo)
+ ];
+
+ return chain(updateRules)(tree, context);
+ };
+}
+
+/**
+ * Update of Otter library V10.0
+ */
+export const updateV10_0 = createSchematicWithMetricsIfInstalled(updateV10_0Fn);
diff --git a/packages/@o3r/localization/src/tools/localization-translate.pipe.spec.ts b/packages/@o3r/localization/src/tools/localization-translate.pipe.spec.ts
index 3e84e9a3d4..1acfdeb79f 100644
--- a/packages/@o3r/localization/src/tools/localization-translate.pipe.spec.ts
+++ b/packages/@o3r/localization/src/tools/localization-translate.pipe.spec.ts
@@ -3,7 +3,7 @@ import { getTestBed, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { Observable, of } from 'rxjs';
-import { LocalizationTranslatePipe } from './localization-translate.pipe';
+import { LocalizationTranslatePipe, O3rLocalizationTranslatePipe } from './localization-translate.pipe';
import { createLocalizationConfiguration, LocalizationModule } from './localization.module';
import { LocalizationService } from './localization.service';
import { LOCALIZATION_CONFIGURATION_TOKEN } from './localization.token';
@@ -36,7 +36,8 @@ describe('LocalizationTranslatePipe', () => {
let localizationService: LocalizationService;
let translate: TranslateService;
- let pipe: LocalizationTranslatePipe;
+ let pipe: O3rLocalizationTranslatePipe;
+ let deprecatedPipe: LocalizationTranslatePipe;
let ref: any;
describe('enableTranslationDeactivation OFF', () => {
@@ -51,12 +52,13 @@ describe('LocalizationTranslatePipe', () => {
providers: [LocalizationService]
}).compileComponents();
- localizationService = TestBed.get(LocalizationService);
+ localizationService = TestBed.inject(LocalizationService);
// initialize TranslateService via configure of LocalizationService
localizationService.configure();
- translate = TestBed.get(TranslateService);
+ translate = TestBed.inject(TranslateService);
ref = new FakeChangeDetectorRef();
- pipe = new LocalizationTranslatePipe(localizationService, translate, ref, TestBed.get(LOCALIZATION_CONFIGURATION_TOKEN));
+ pipe = new O3rLocalizationTranslatePipe(localizationService, translate, ref, TestBed.inject(LOCALIZATION_CONFIGURATION_TOKEN));
+ deprecatedPipe = new LocalizationTranslatePipe(localizationService, translate, ref, TestBed.inject(LOCALIZATION_CONFIGURATION_TOKEN));
expect(() => localizationService.toggleShowKeys()).toThrow();
});
@@ -80,25 +82,30 @@ describe('LocalizationTranslatePipe', () => {
}]
}).compileComponents();
- localizationService = TestBed.get(LocalizationService);
+ localizationService = TestBed.inject(LocalizationService);
// initialize TranslateService via configure of LocalizationService
localizationService.configure();
- translate = TestBed.get(TranslateService);
+ translate = TestBed.inject(TranslateService);
ref = new FakeChangeDetectorRef();
- pipe = new LocalizationTranslatePipe(localizationService, translate, ref, TestBed.get(LOCALIZATION_CONFIGURATION_TOKEN));
+ pipe = new O3rLocalizationTranslatePipe(localizationService, translate, ref, TestBed.inject(LOCALIZATION_CONFIGURATION_TOKEN));
+ deprecatedPipe = new LocalizationTranslatePipe(localizationService, translate, ref, TestBed.inject(LOCALIZATION_CONFIGURATION_TOKEN));
});
it('Should not translate if ShowKeys is activated', () => {
localizationService.toggleShowKeys();
expect(pipe.transform('test')).toEqual('test');
+ expect(deprecatedPipe.transform('test')).toEqual('test');
expect(pipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('testParams');
+ expect(deprecatedPipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('testParams');
});
it('Should translate if ShowKeys is no activated', () => {
expect(pipe.transform('test')).toEqual('This is a test');
+ expect(deprecatedPipe.transform('test')).toEqual('This is a test');
expect(pipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('This is a test with param-1 and param-2');
+ expect(deprecatedPipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('This is a test with param-1 and param-2');
});
});
@@ -122,27 +129,31 @@ describe('LocalizationTranslatePipe', () => {
}
]
}).compileComponents();
- localizationService = TestBed.get(LocalizationService);
+ localizationService = TestBed.inject(LocalizationService);
// initialize TranslateService via configure of LocalizationService
localizationService.configure();
- translate = TestBed.get(TranslateService);
+ translate = TestBed.inject(TranslateService);
ref = new FakeChangeDetectorRef();
- pipe = new LocalizationTranslatePipe(localizationService, translate, ref, TestBed.get(LOCALIZATION_CONFIGURATION_TOKEN));
+ pipe = new O3rLocalizationTranslatePipe(localizationService, translate, ref, TestBed.inject(LOCALIZATION_CONFIGURATION_TOKEN));
+ deprecatedPipe = new LocalizationTranslatePipe(localizationService, translate, ref, TestBed.inject(LOCALIZATION_CONFIGURATION_TOKEN));
});
it('Should not translate if ShowKeys is activated', () => {
localizationService.toggleShowKeys();
expect(pipe.transform('test')).toEqual('test');
+ expect(deprecatedPipe.transform('test')).toEqual('test');
expect(pipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('testParams');
+ expect(deprecatedPipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('testParams');
});
it('Should display both key and value if ShowKeys is no activated', () => {
expect(pipe.transform('test')).toEqual('test - This is a test');
+ expect(deprecatedPipe.transform('test')).toEqual('test - This is a test');
expect(pipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('testParams - This is a test with param-1 and param-2');
+ expect(deprecatedPipe.transform('testParams', '{param1: "with param-1", param2: "and param-2"}')).toEqual('testParams - This is a test with param-1 and param-2');
});
});
});
-
});
diff --git a/packages/@o3r/localization/src/tools/localization-translate.pipe.ts b/packages/@o3r/localization/src/tools/localization-translate.pipe.ts
index 9e5ff770fb..a33a524c88 100644
--- a/packages/@o3r/localization/src/tools/localization-translate.pipe.ts
+++ b/packages/@o3r/localization/src/tools/localization-translate.pipe.ts
@@ -4,34 +4,35 @@ import { Subscription } from 'rxjs';
import { LocalizationConfiguration } from '../core';
import { LocalizationService } from './localization.service';
import { LOCALIZATION_CONFIGURATION_TOKEN } from './localization.token';
+
/**
* TranslatePipe class adding debug functionality
*/
-@Pipe({name: 'translate', pure: false})
-export class LocalizationTranslatePipe extends TranslatePipe implements PipeTransform {
+@Pipe({name: 'o3rTranslate', pure: false})
+export class O3rLocalizationTranslatePipe extends TranslatePipe implements PipeTransform {
/**
* Internal subscription to the LocalizationService showKeys mode changes
*/
- private readonly onShowKeysChange?: Subscription;
+ protected readonly onShowKeysChange?: Subscription;
/**
* Internal subscription to the LocalizationService key mapping
*/
- private onKeyChange?: Subscription;
+ protected onKeyChange?: Subscription;
/**
* Should we display keys instead of translations
*/
- private showKeys = false;
+ protected showKeys = false;
/** last key queried */
- private lastQueryKey?: string;
+ protected lastQueryKey?: string;
/** last key resolved */
- private lastResolvedKey?: string;
+ protected lastResolvedKey?: string;
- constructor(private readonly localizationService: LocalizationService, translateService: TranslateService, private readonly changeDetector: ChangeDetectorRef,
- @Inject(LOCALIZATION_CONFIGURATION_TOKEN) private readonly localizationConfig: LocalizationConfiguration) {
+ constructor(protected readonly localizationService: LocalizationService, translateService: TranslateService, protected readonly changeDetector: ChangeDetectorRef,
+ @Inject(LOCALIZATION_CONFIGURATION_TOKEN) protected readonly localizationConfig: LocalizationConfiguration) {
super(translateService, changeDetector);
if (localizationConfig.enableTranslationDeactivation) {
@@ -83,3 +84,10 @@ export class LocalizationTranslatePipe extends TranslatePipe implements PipeTran
}
}
}
+
+/**
+ * TranslatePipe class adding debug functionality
+ * @deprecated please use O3rLocalizationTranslatePipe, will be removed in v12.
+ */
+@Pipe({name: 'translate', pure: false})
+export class LocalizationTranslatePipe extends O3rLocalizationTranslatePipe implements PipeTransform {}
diff --git a/packages/@o3r/localization/src/tools/localization.module.ts b/packages/@o3r/localization/src/tools/localization.module.ts
index 811ac5c173..5edaf230b4 100644
--- a/packages/@o3r/localization/src/tools/localization.module.ts
+++ b/packages/@o3r/localization/src/tools/localization.module.ts
@@ -5,7 +5,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { DynamicContentModule } from '@o3r/dynamic-content';
import { DEFAULT_LOCALIZATION_CONFIGURATION, LocalizationConfiguration } from '../core';
import { LocalizationTranslateDirective } from './localization-translate.directive';
-import { LocalizationTranslatePipe } from './localization-translate.pipe';
+import { LocalizationTranslatePipe, O3rLocalizationTranslatePipe } from './localization-translate.pipe';
import { LocalizationService } from './localization.service';
import { LOCALIZATION_CONFIGURATION_TOKEN } from './localization.token';
import { LocalizedCurrencyPipe } from './localized-currency.pipe';
@@ -37,9 +37,9 @@ export function localeIdNgBridge(localizationService: LocalizationService) {
export const CUSTOM_LOCALIZATION_CONFIGURATION_TOKEN = new InjectionToken
>('Partial Localization configuration');
@NgModule({
- declarations: [LocalizationTranslatePipe, LocalizationTranslateDirective, LocalizedDatePipe, LocalizedDecimalPipe, LocalizedCurrencyPipe],
+ declarations: [O3rLocalizationTranslatePipe, LocalizationTranslatePipe, LocalizationTranslateDirective, LocalizedDatePipe, LocalizedDecimalPipe, LocalizedCurrencyPipe],
imports: [TranslateModule, BidiModule, DynamicContentModule, CommonModule],
- exports: [TranslateModule, LocalizationTranslatePipe, LocalizationTranslateDirective, LocalizedDatePipe, LocalizedDecimalPipe, LocalizedCurrencyPipe],
+ exports: [TranslateModule, O3rLocalizationTranslatePipe, LocalizationTranslatePipe, LocalizationTranslateDirective, LocalizedDatePipe, LocalizedDecimalPipe, LocalizedCurrencyPipe],
providers: [
{provide: LOCALIZATION_CONFIGURATION_TOKEN, useFactory: createLocalizationConfiguration, deps: [[new Optional(), CUSTOM_LOCALIZATION_CONFIGURATION_TOKEN]]},
{provide: LOCALE_ID, useFactory: localeIdNgBridge, deps: [LocalizationService]},
diff --git a/packages/@o3r/localization/testing/mocks/angular.mocks.json b/packages/@o3r/localization/testing/mocks/angular.mocks.json
new file mode 100644
index 0000000000..c34167f9cc
--- /dev/null
+++ b/packages/@o3r/localization/testing/mocks/angular.mocks.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://raw.githubusercontent.com/angular/angular-cli/master/packages/angular/cli/lib/config/workspace-schema.json",
+ "version": 1,
+ "newProjectRoot": ".",
+ "projects": {
+ "test-project": {
+ "projectType": "application",
+ "root": ".",
+ "sourceRoot": "./src",
+ "prefix": "tst",
+ "architect": {
+ "build": {
+ "builder": "",
+ "options": {
+ "tsConfig": "tsconfig.json"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/@o3r/localization/testing/mocks/package.mocks.json b/packages/@o3r/localization/testing/mocks/package.mocks.json
new file mode 100644
index 0000000000..c64b320ebd
--- /dev/null
+++ b/packages/@o3r/localization/testing/mocks/package.mocks.json
@@ -0,0 +1,5 @@
+{
+ "name": "test-project",
+ "version": "0.0.0",
+ "description": "Test project"
+}
diff --git a/packages/@o3r/rules-engine/src/components/rules-engine/rule-actions/rule-actions-pres.template.html b/packages/@o3r/rules-engine/src/components/rules-engine/rule-actions/rule-actions-pres.template.html
index ec0bedb6dd..6bf6c1f9dd 100644
--- a/packages/@o3r/rules-engine/src/components/rules-engine/rule-actions/rule-actions-pres.template.html
+++ b/packages/@o3r/rules-engine/src/components/rules-engine/rule-actions/rule-actions-pres.template.html
@@ -10,8 +10,8 @@
Set Fact
@@ -19,8 +19,8 @@
Update Config {{action.component}} {{action.library}}
@@ -28,8 +28,8 @@