diff --git a/assets/schemas/component-type-example.png b/assets/schemas/component-type-example.png new file mode 100644 index 0000000000..68774055d4 Binary files /dev/null and b/assets/schemas/component-type-example.png differ diff --git a/docs/README.md b/docs/README.md index 08536edae8..f54bfa34ed 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,7 @@ The documentation is sorted by topic but in the table below, you shall find the | @o3r/apis-manager | Service to help you communicate with your APIs | @o3r/dev-tools | [APIS_MANAGER](https://github.com/AmadeusITGroup/otter/blob/main/packages/%40o3r/apis-manager/README.md) | | @o3r/application | Provides development tools for your Otter application | @o3r/core
@o3r/dev-tools | | | @o3r/chrome-devtools | Chrome plugin to debug your Otter application | N/A | [chrome-devtools](./dev-tools/chrome-devtools.md) | -| @o3r/components | Component related features (Component replacement, CMS compatibility, helpers, pipes, debugging developer tools...)
Comes with an integrated ng builder | @o3r/analytics
@o3r/build-helpers
@o3r/configuration
@o3r/core
@o3r/dev-tools
@o3r/extractors
@o3r/localization
@o3r/logger
@o3r/schematics
@o3r/testing | [COMPONENT_STRUCTURE](./components/COMPONENT_STRUCTURE.md)
[COMPONENT_STYLE_OVERRIDE](./components/COMPONENT_STYLE_OVERRIDE.md)
[CONTAINER_PRESENTER](./components/CONTAINER_PRESENTER.md)
[FIXTURES](./components/FIXTURES.md)
[NAMING_CONVENTION](./components/NAMING_CONVENTION.md)
[COMPONENT_REPLACEMENT](./components/COMPONENT_REPLACEMENT.md)
[CMS_ADAPTERS](./cms-adapters/CMS_ADAPTERS.md) | +| @o3r/components | Component related features (Component replacement, CMS compatibility, helpers, pipes, debugging developer tools...)
Comes with an integrated ng builder | @o3r/analytics
@o3r/build-helpers
@o3r/configuration
@o3r/core
@o3r/dev-tools
@o3r/extractors
@o3r/localization
@o3r/logger
@o3r/schematics
@o3r/testing | [COMPONENT INTRODUCTION](./components/INTRODUCTION.md)
[COMPONENT_STYLE_OVERRIDE](./components/COMPONENT_STYLE_OVERRIDE.md)
[CONTAINER_PRESENTER](./components/CONTAINER_PRESENTER.md)
[FIXTURES](./components/FIXTURES.md)
[COMPONENT_REPLACEMENT](./components/COMPONENT_REPLACEMENT.md)
[CMS_ADAPTERS](./cms-adapters/CMS_ADAPTERS.md) | | @o3r/configuration | Configuration related features (CMS compatibility, Configuration override, store and debugging) | @o3r/core
@o3r/dev-tools
@o3r/logger
@o3r/testing | [OVERVIEW](./configuration/OVERVIEW.md)
[CONFIGURATION_SUPPORTED_EXTRACTOR](./configuration/CONFIGURATION_SUPPORTED_EXTRACTOR.md)
[CMS_ADAPTERS](./cms-adapters/CMS_ADAPTERS.md) | | @o3r/core | Foundation for all the packages (interfaces, core helpers) and schematics to generate your components/services etc. | N/A | [START_NEW_APPLICATION](./core/START_NEW_APPLICATION.md)
[DEVELOPER](./core/DEVELOPER.md)
[OTTER_ANGULAR_TOOLS](./core/OTTER_ANGULAR_TOOLS.md) | | @o3r/design | Tools to generate theme from design materials | N/A | [TECHNICAL_DOCUMENTATION](./design/TECHNICAL_DOCUMENTATION.md) | diff --git a/docs/analytics/TRACK_EVENTS.md b/docs/analytics/TRACK_EVENTS.md index e4c63b64c9..fd7686c75c 100644 --- a/docs/analytics/TRACK_EVENTS.md +++ b/docs/analytics/TRACK_EVENTS.md @@ -1,7 +1,7 @@ # Track UI Events The main purpose of this mechanism is to ease event tracking at component level. -You can capture your events via the tracking event directives (exposed in the [TrackEventsModule](#TrackEventsModule)) +You can capture your events via the tracking event directives (exposed in the [TrackEventsModule](#TrackEventsModule)) and the [EventTrackService](#EventTrackService). You can access all these events via the [EventTrackService](#EventTrackService). @@ -37,9 +37,9 @@ class MyComponent extends Trackable, ... { ``` ## TrackEventsModule -The `TrackEventsModule` contains directives to help you track standard event such as the `TrackClickDirective` or +The `TrackEventsModule` contains directives to help you track standard event such as the `TrackClickDirective` or `TrackFocusDirective`. -You can track more standard ui event with the `TrackEventsDirective` and even create your own component events +You can track more standard ui event with the `TrackEventsDirective` and even create your own component events (see [Analytics Events](./ANALYTICS.md)). Note that all these events will be stored as UI Events in the [EventTrackService](#EventTrackService). ```html @@ -56,7 +56,7 @@ Note that all these events will be stored as UI Events in the [EventTrackService ### TrackEvents directive -The directive will listen to the events on the element on which was applied and will expose the event captured using the track service. +The directive will listen to the events on the element on which was applied and will expose the event captured using the track service. | Input Name | Description | Possible Values | | ----------------- | ------------------------------------------------------ | ------------------------------- | @@ -83,10 +83,10 @@ If the object passed in `trackEventContext` has to be updated in the model file ```html
... - ...
@@ -94,7 +94,7 @@ If the object passed in `trackEventContext` has to be updated in the model file in component.ts file ```typescript -eventModel = {name: 'searchBtnMouseEvent'}; +eventModel = {name: 'searchBtnMouseEvent'}; ``` in eventContext pipe.ts file @@ -107,64 +107,64 @@ transform(value: any, itinerary: any): any { ### Application level -At application level a subscription can be done to the observable emitted by the track events service. +At application level a subscription can be done to the observable emitted by the track events service. You can enhance your analytics data and merge/concatenate/modify the event from the `TrackEventsService` with your own application store. # Performance metrics -There are several aspects of a web application that can impact its performance. Network conditions, CPU processing, server-side tasks are a few of them. -Checking how long it took to load the page is not enough to measure the application performances. -Quickly loading something that is not meaningful nor interactive means nothing to the user. That's why one must improve the load -time AND the perceived performance (aka how fast the user perceives the application). -Some of those metrics (load time related and perception metrics) are described below. +There are several aspects of a web application that can impact its performance. Network conditions, CPU processing, server-side tasks are a few of them. +Checking how long it took to load the page is not enough to measure the application performances. +Quickly loading something that is not meaningful nor interactive means nothing to the user. That's why one must improve the load +time AND the perceived performance (aka how fast the user perceives the application). +Some of those metrics (load time related and perception metrics) are described below. ### First load Mark the first load metrics using the [Performance API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming). -This has to be called only once in a single page application, as it is only meaningful for the initial page load. [FirstLoadDataPayload](https://github.com/AmadeusITGroup/otter/blob/main/packages/@o3r/analytics/src/contracts/events-contracts.ts) -interface is the model object for this mark. +This has to be called only once in a single page application, as it is only meaningful for the initial page load. [FirstLoadDataPayload](https://github.com/AmadeusITGroup/otter/blob/main/packages/@o3r/analytics/src/contracts/events-contracts.ts) +interface is the model object for this mark. ### First paint ([FP](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)) -This is one of the first metrics for perceived performance. Basically, it measures the time the app takes to answer a -user's first question: Is something happening? Is the navigation successful ? Has the server responded? +This is one of the first metrics for perceived performance. Basically, it measures the time the app takes to answer a +user's first question: Is something happening? Is the navigation successful ? Has the server responded? The First Paint (FP) measures the time it takes from the start of the navigation to, for example, display the loading indication. ### First Meaningful Paint ([FMP](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)) -Also for perceived performance, FMP measures the time the app takes to render enough content for users to engage. A simple strategy for this metric is to mark what's called hero elements (most important +Also for perceived performance, FMP measures the time the app takes to render enough content for users to engage. A simple strategy for this metric is to mark what's called hero elements (most important elements in the page) and register the time it took to display them -### Time to Interactive ([TTI](https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive)) -TTI marks the time when the user can effectively interact with the app. This is closely related to the fact that, in some implementations, the app may have rendered meaningful information +### Time to Interactive ([TTI](https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive)) +TTI marks the time when the user can effectively interact with the app. This is closely related to the fact that, in some implementations, the app may have rendered meaningful information (measured by FMP) but, in the background, it's still doing some kind of computation that blocks any possible interaction with the page. -The time to interactive is quite tricky as it not only depends on the relevant data readiness, but also on -component internal display mechanics. -If you know exactly where javascript will trigger a layout change (e.g. by passing a boolean variable to true), it's possible to measure the upper bound for the rendering. +The time to interactive is quite tricky as it not only depends on the relevant data readiness, but also on +component internal display mechanics. +If you know exactly where javascript will trigger a layout change (e.g. by passing a boolean variable to true), it's possible to measure the upper bound for the rendering. In addition, during a component development, you can't possibly know beforehand if the component will be relevant for a TTI or not, since it depends on the page itself. For example, the display of a cart component may be relevant for TTI in a given page and not relevant at all in others. Hence, you cannot really define your TTI logic at component level. -Given the above facts, we advise to split the TTI metric in two: - * __dataReady__: This probe marks the time when all the data, needed to the page be interactive, is available - * __TTI per component__: data ready for each component; we advise to implement it later, since it may impact the complexity of the code +Given the above facts, we advise to split the TTI metric in two: + * __dataReady__: This probe marks the time when all the data, needed to the page be interactive, is available + * __TTI per component__: data ready for each component; we advise to implement it later, since it may impact the complexity of the code -For the time being we will consider only the implementation of __data ready__ +For the time being we will consider only the implementation of __data ready__ ### Network and server-side metrics -As the browser can't understand when a route event happens in an SPA, the NavigationTimingAPI can't be directly used apart from the first page load at most. +As the browser can't understand when a route event happens in an SPA, the NavigationTimingAPI can't be directly used apart from the first page load at most. Subsequent routing changes won't profit of the API connection timings. In regard of the __server fetches__ (filter out from the resource timing API), the [PerformanceMetricPlugin](https://github.com/AmadeusITGroup/otter/blob/main/packages/@ama-sdk/core/src/plugins/perf-metric/perf-metric.fetch.ts) -has been put in place to get the metrics associated to server calls. -Check [ServerCallMetric](https://github.com/AmadeusITGroup/otter/blob/main/packages/@o3r/analytics/src/contracts/events-contracts.ts) -model to see which information is saved for each call. +has been put in place to get the metrics associated to server calls. +Check [ServerCallMetric](https://github.com/AmadeusITGroup/otter/blob/main/packages/@o3r/analytics/src/contracts/events-contracts.ts) +model to see which information is saved for each call. ## How to mark performance metrics? -The __EventTrackService__ plugs itself to the [NavigationEnd](https://angular.io/api/router/NavigationEnd) router, to handle the performance metrics and exposes the performance object as a stream (observable). -The performance metric object structure is defined by __PerfEventPayload__ interface which can be found [here](https://github.com/AmadeusITGroup/otter/blob/main/packages/@o3r/analytics/src/contracts/events-contracts.ts). -The service provides a way to activate/deactivate performance measurements. By default, it's __activated__ and we expose a public method called __togglePerfTracking__ to activate/deactivate it. +The __EventTrackService__ plugs itself to the [NavigationEnd](https://angular.io/api/router/NavigationEnd) router, to handle the performance metrics and exposes the performance object as a stream (observable). +The performance metric object structure is defined by __PerfEventPayload__ interface which can be found [here](https://github.com/AmadeusITGroup/otter/blob/main/packages/@o3r/analytics/src/contracts/events-contracts.ts). +The service provides a way to activate/deactivate performance measurements. By default, it's __activated__ and we expose a public method called __togglePerfTracking__ to activate/deactivate it. For instance if you want to deactivate it, call this in your app: ```typescript import {EventTrackService} from '@o3r/analytics'; @@ -175,7 +175,7 @@ constructor(trackService: EventTrackService) { ``` ### Tracking configuration You can override the default configuration via a configuration token ([EVENT_TRACK_SERVICE_CONFIGURATION](https://github.com/AmadeusITGroup/otter/blob/main/packages/@o3r/analytics/src/services/event-track/event-track.configuration.ts)). -Example of configuration override: +Example of configuration override: ```typescript // in app module ... @@ -192,7 +192,7 @@ This mark is populated by default by the __EventTrackService__ when the [Navigat #### First paint (FP) -You can mark the time the loading is rendered. +You can mark the time the loading is rendered. * If the app has a loading indicator at [NavigationStart](https://angular.io/api/router/NavigationStart), this is when we want to mark the first paint. ```typescript // app component @@ -209,9 +209,9 @@ You can mark the time the loading is rendered. } } ``` -* If __index.html__ contains a loading indicator, it will be rendered even before loading angular; -In this case FP will be marked by the browser api. You can activate this behaviour in the tracking service and override the '_useBrowserApiForFirstFP_' config property to _true_; -If the browser does not have [performance entry 'paint' api](https://developer.mozilla.org/en-US/docs/Web/API/Performance/getEntriesByType), nothing will be marked. +* If __index.html__ contains a loading indicator, it will be rendered even before loading Angular; +In this case FP will be marked by the browser api. You can activate this behaviour in the tracking service and override the '_useBrowserApiForFirstFP_' config property to _true_; +If the browser does not have [performance entry 'paint' api](https://developer.mozilla.org/en-US/docs/Web/API/Performance/getEntriesByType), nothing will be marked. ```typescript // in app module ... @@ -221,7 +221,7 @@ If the browser does not have [performance entry 'paint' api](https://developer.m ] ``` * __markFP__ method from tracking service should be called when the loading indicator is triggered - + #### First Meaningful Paint (FMP) You can mark FMP is in the _ngAfterViewInit_ of each page ```typescript @@ -235,7 +235,7 @@ ngAfterViewInit() { ``` #### Data Ready This will depend on your application. -For example, on the availability page, mark _data ready_ when the calendar and offers data are available; +For example, on the availability page, mark _data ready_ when the calendar and offers data are available; ```typescript // upsell page component ... @@ -262,7 +262,7 @@ export class UpsellComponent implements OnInit, OnDestroy, Configurable` from `@o3r/core`. + +```typescript +import {Context} from '@o3r/core'; + +export interface DummyPresContextInput { + /** Example of input */ + dummyInput: string; +} + +export interface DummyPresContextOutput { + /** Example of output */ + onDummyOutput: number; +} + +export interface DummyPresContext extends Context {} +``` + ### Component's class Here we need to do a couple of things: @@ -243,8 +269,8 @@ export class DummyContComponent implements DynamicConfigurable, }; } - public dummyOutput() { - console.log('output'); + public dummyOutput(event: number) { + console.log('output', event); } } ```` @@ -270,21 +296,24 @@ Instead, we will simply use an ``ng-template`` tag to which we apply the Otter ` ## Known limitations -The main limitation is that it is not possible to apply any modification to the ``host`` component created by a factory. +The main limitation is that it is not possible to apply any modifications to the ``host`` component created by a factory. -What it means is that any of those: +This means that any of those following are not possible through an ``ng-template`` and ``c11n`` combination: ````html - + ```` -Are not possible through an ``ng-template`` and ``c11n`` combination. - -Though there is a solution for the first example in making the value an input, and bind it inside the component using +Though there is a solution for the first example in making `class` an input, and bind it inside the component using the [HostBinding](https://angular.io/api/core/HostBinding) decorator, there is no actual solution for applying directive. -A [feature request](https://github.com/angular/angular/issues/8785) has been opened for a long time and finally made it -to the "Future" section and Angular's roadmap. + +## Naming convetion + +| Attribute | Pattern | +| --------------------------- | ----------------------------------------- | +| **Context file name** | *.context.ts | +| **Context interface names** | *ContextInput / *ContextOutput / *Context | diff --git a/docs/components/COMPONENT_STRUCTURE.md b/docs/components/COMPONENT_STRUCTURE.md deleted file mode 100644 index ef503aab48..0000000000 --- a/docs/components/COMPONENT_STRUCTURE.md +++ /dev/null @@ -1,238 +0,0 @@ -# Component structure - -This document describes the structure and the content of component files. - -``` - -├── container -│   ├── README.md -│   ├── -cont.component.ts -│   ├── -cont.config.ts -│   ├── -cont.context.ts -│   ├── -cont.fixture.ts -│   ├── -cont.module.ts -│   ├── -cont.spec.ts -│   ├── -cont.template.html -│   └── index.ts -├── contracts -│   ├── .model.ts -├── directives -│   ├── .directive.ts -├── presenter -│   ├── -pres.component.ts -│   ├── -pres.config.ts -│   ├── -pres.context.ts -| ├── -pres.localization.json -| ├── -pres.translation.ts -│   ├── -pres.fixture.ts -│   ├── -pres.module.ts -│   ├── -pres.spec.ts -│   ├── -pres.style.scss -│   ├── -pres.style.theme.scss -│   ├── -pres.template.html -│   └── index.ts -├── sub-components -│   └── -├── .int-spec.ts -└── index.ts -``` - -This is a general tree for a component that respects the container/presenter pattern. -There are three folders: - -* `container` component folder; It contains the files related to the container component. Check the [container / presenter documentation](./CONTAINER_PRESENTER.md) for more details -* `presenter` component folder; It contains the files related to the presenter component. Check the [container / presenter documentation](./CONTAINER_PRESENTER.md) for more details -* `sub-components` folder; A component may be composed of subcomponents. They should be located in a dedicated subcomponents folder inside the component folder. We want to keep all components which belongs to the same functional area and are not blocks in the same functional folder. -Nevertheless, if a component is shared among different functional blocks, it will have to be set inside the dedicated shared folder (at the root of components folder). - -Optionally, there could be other two folders: - -* `contracts`; used to contain all shared models or interfaces over your components (between container and presenter, subcomponents or other components). -* `directives`, which contains directives used in the context of your component. Keeping them in a dedicated folder will help you extract them if they have to be extracted in order to be shared. - -If you don't need container/presenter structure because your component is only a presentational component, then the structure will be: - -``` - -├── contracts -│   ├── .model.ts -├── directives -│   ├── .directive.ts -├── -pres.component.ts -├── -pres.config.ts -├── -pres.context.ts -├── -pres.localization.json -├── -pres.translation.ts -├── -pres.fixture.ts -├── -pres.module.ts -├── -pres.spec.ts -├── -pres.style.scss -├── -pres.style.theme.scss -├── -pres.template.html -└── index.ts -``` - -## Content / files description - -### Configuration (`.config.ts`) - -Check the [configuration docs](../configuration/OVERVIEW.md) - -### Context (`.context.ts`) - -It is used to define the contract to interact with your component, defining the set of dynamic inputs and outputs that a component has. -It is structured into three interfaces: - -* `*ContextInput` interface (e.g. `MyComponentContextInput`): it contains all the inputs of a component. Fields must have a documentation. -* `*ContextOutput` interface (e.g. `MyComponentContextOutput`): it contains all the outputs of a component. Fields must have a documentation. -* interface `MyComponentContext`: it brings together `ContextInput` and `ContextOutput`, extending `Context` from `@o3r/core`. - -```typescript -import {Context} from '@o3r/core'; - -export interface MyComponentContextInput { - - input1: number; - - input2: TemplateRef; -} - -export interface MyComponentContextOutput { - - output1: number; - - output2: string; - -} - -export interface MyComponentContext extends Context {} -``` - -More info can be found in the [Component replacement documentation](./COMPONENT_REPLACEMENT.md) - -### Translation (`*.translation.ts`) - -It is used to define the localization variables used by component template. my-component.translation.ts file typically defines an interface which extends `Translation` from `@o3r/core` with all possible variable names used by your presenter template. It also exports a constant which satisfies the above contract. The values for each property are localization keys (real keys from localization bundle). - -```typescript -import {Translation} from '@o3r/core'; - -export interface MyComponentPresTranslation extends Translation { - prop1: string; - prop2: string; -} - -export const translations: MyComponentPresTranslation = { - prop1: 'o3r-my-component-pres.somekey1', - prop2: 'o3r-my-component-pres.somekey2' -}; -``` - -### Localization (`*.localization.json`) - -It defines an object being key/value pairs. Each value is a json object having `description` and `defaultValue` properties. Eventually you can reference a global key via $ref using relative path to `global-localization.json` which sits in `src` or in different package in dependencies. The purpose of this file is to provide a default localization for component so that library user can start building pages using components without worrying about localization. `*.localization.json` specifies only default values in english. - -```typescript -{ - 'o3r-my-component-pres.somekey1': { - 'description': 'This is somekey1 description for translators', - 'defaultValue': 'This is my default value 1' - }, - 'o3r-my-component-pres.somekey2': { - 'description': 'This is somekey2 description for translators', - 'defaultValue': 'This is my default value 2' - }, - 'o3r-my-component-pres.someglobalkey1': { - '$ref': '../global.localization.json#/someglobalkey1' - }, - 'o3r-my-component-pres.someglobalkey2': { - '$ref': '@scope/common/global.localization.json#/someglobalkey2' - } -} -``` - -### Fixtures (`*.fixtures.ts`) - -It defines the component object model used for testing. In other words, it is a class which contains mainly a set of accessors to the DOM elements of the component. -There is a dedicated [fixtures documentation](./FIXTURES.md) to explain in details how to write and use them. - -### Unit test (`*.spec.ts`) - -Unit test for the component using Angular TestBed suite. - -### Integration test (`*.int-spec.ts`) - -Test interactions between components, also using fixtures. - -### Style (`*.style.scss`) - -It's the style relative to the component. It is using the scss variables defined in `.style.theme.scss`. -By default, `None` view encapsulation is used. - -### Style theme - -It's the file to define the scss variables used inside the component. -In our library, variables, fonts, mixins and all the basic styles are in the package '@o3r/styling'. -If you want to use them, for example `@use "@o3r/styling" as o3r;`. - -### Template (`*.template.html`) - -Template of the component. - -### Component class (`*.component.ts`) - -This is the core of a component. Here is where you have the Angular decorators for the component itself. -By default, it implements Configurable with generic of the class defined in my `.config.ts`, as explained in [Configuration](#configuration) . -It also implements the context, defined in `.context.ts`, as explained in [Context](#context). -We are compliant with Angular best practice, and we enforce rules using ts-linter. - -### Module (`*.module.ts`) - -It defines the `NgModule` for the component. - -### Index (`index.ts`) - -It is used as a barrel to ease the import's paths. -We used to export: - -* module -* context -* configuration - -## Runtime debugging - -### Enable Chrome extension debugging - -The Otter framework provides an [Otter Chrome Extension](https://chrome.google.com/webstore/detail/otter-devtools/aejabgendbpckkdnjaphhlifbhepmbne) to help debug the application. -To enable the communication with the [Otter Devtools](../dev-tools/chrome-devtools.md) the two following steps are required: - -1. Import the Devtools module into the application AppModule: - -```typescript -import { ComponentsDevtoolsModule } from '@o3r/components'; - -@NgModule({ - imports: [ - ..., - ComponentsDevtoolsModule - ] -}) -export class AppModule { } -``` - -2. Activate the debug message service: - -```typescript -import { ComponentsDevtoolsMessageService } from '@o3r/components'; - -@Component({ ... }) -export class AppComponent { - constructor(componentsDevtoolsMessageService: ComponentsDevtoolsMessageService) { - if (IS_DEBUG_MODE) { - componentsDevtoolsMessageService.activate(); - } - } -} -``` - -> **Note**: get more details on [dev tools session](../dev-tools/chrome-devtools.md) diff --git a/docs/components/CONTAINER_PRESENTER.md b/docs/components/CONTAINER_PRESENTER.md index 188f29849d..fea6eae4e1 100644 --- a/docs/components/CONTAINER_PRESENTER.md +++ b/docs/components/CONTAINER_PRESENTER.md @@ -1,6 +1,6 @@ # Container / Presenter -We encourage developers to decouple components into containers and presenters. From a UI perspective it is a good practice to separate access of Data/ business logic form pure presentation, this allows developer to reuse presenters in other parts of the code with different data or having a container linked to multiple presenters, in case you want to display the same thing with a totally different user experience. +From a UI perspective it is a good practice to separate access of data/business logic form pure presentation. This allows developers to reuse presenters in other parts of the code with different data or having a container linked to multiple presenters, in case you want to display the same thing with a totally different user experience. Some references: @@ -13,68 +13,42 @@ Some references: A component implementing the container/presenter pattern is split into two Angular components: the container and the presenter. -It should have a global _index.ts_ module file. +It should have a global `index.ts` module file. ### Container -The container is located in the _container_ folder of the component. - -It must implement the template outlet pattern in order to get the ability to customise the presentation layer. +The container is located in the __container__ folder of the component. It must have a dedicated presenter component which will orchestrate the presentation. It should follow the following naming convention: -| Attribute | Pattern | -| ------------- |:-------------| -| **Component file name** | *-cont.component.ts | -| **Selector name** | *-cont | -| **Component name** | *ContComponent | -| **Configuration file name** | *-cont.config.ts | -| **Configuration name** | *ContConfig | -| **Context file name** | *-cont.context.ts | -| **Context interface names** | *ContContextInput / *ContContextOutput / *ContContext | -| **Fixture file name** | *-cont.fixture.ts | -| **Fixture name** | *ContFixture | -| **Module file name** | *-cont.module.ts | -| **Module name** | *ContModule | -| **Template file name** | *-cont.template.html | -| **Unit test file name** | *-cont.spec.ts | - -It has its own _index.ts_ file exporting: - -* Module file -* Context file -* Configuration file +| Attribute | Pattern | +| ----------------------- | -------------------- | +| **Component file name** | *-cont.component.ts | +| **Selector name** | *-cont | +| **Component name** | *ContComponent | +| **Template file name** | *-cont.template.html | +| **Unit test file name** | *-cont.spec.ts | + +It has its own _index.ts_ file exporting the component. Later, it could export the customization files linked like `*-pres.config.ts`. ### Presenter -The presenter is located in the _presenter_ folder of the component. +The presenter is located in the __presenter__ folder of the component. It should follow the following naming convention: -| Attribute | Pattern | -| ------------- |:-------------| -| **Component file name** | *-pres.component.ts | -| **Selector name** | *-pres | -| **Component name** | *PresComponent | -| **Configuration file name** | *-pres.config.ts | -| **Configuration name** | *PresConfig | -| **Context file name** | *-pres.context.ts | -| **Context interface names** | *PresContextInput / *PresContextOutput / *PresContext | -| **Fixture file name** | *-pres.fixture.ts | -| **Fixture name** | *PresFixture | -| **Module file name** | *-pres.module.ts | -| **Module name** | *PresModule | -| **Template file name** | *-pres.template.html | -| **Style file name** | *-pres.style.scss | -| **Unit test file name** | *-pres.spec.ts | - -It has its own _index.ts_ file exporting: - -* Module file -* Context file -* Configuration file +| Attribute | Pattern | +| ----------------------- | -------------------- | +| **Component file name** | *-pres.component.ts | +| **Selector name** | *-pres | +| **Component name** | *PresComponent | +| **Template file name** | *-pres.template.html | +| **Style file name** | *-pres.style.scss | +| **Unit test file name** | *-pres.spec.ts | + +It has its own _index.ts_ file exporting the component. Later, it could export the customization files linked like `*-pres.translation.ts` or `*-pres.config.ts`. ### Example @@ -83,26 +57,18 @@ Example of a component implementing the container/presenter pattern: ``` passengers/ container/ + [passengers-cont.module.ts] passengers-cont.component.ts - passengers-cont.module.ts passengers-cont.template.html - passengers-cont.config.ts - passengers-cont.context.ts passengers-cont.spec.ts index.ts contracts/ passenger.model.ts - directives/ - my-directive.directive.ts presenter/ + [passengers-pres.module.ts] passengers-pres.component.ts - passengers-pres.module.ts passengers-pres.template.html passengers-pres.style.scss - passengers-pres.style.theme.scss - passengers-pres.config.ts - passengers-pres.context.ts - passengers-pres.fixture.ts passengers-pres.spec.ts index.ts sub-components/ @@ -112,11 +78,9 @@ passengers/ ## Guidelines summary -* A component interacting with external entities (store, services, etc.) should be split into a container and a presenter -* A component with no interactions with external entities should only be a presenter -* By definition, a block is always split into container/presenter -* Subcomponents are located in the related block subcomponents folder. If the subcomponent is a block, it will then be set either in the components root folder (if it has a functional meaning), or at the root of the functional folder in a dedicated sub folder. -* A component shared among different blocks and hosted in the same functional folder, should be placed in a shared folder under the functional one. +* A component interacting with external entities (store, services, etc.) may be split into a container and a presenter +* Subcomponents are located in the subcomponents folder of the related block. If the subcomponent is a block, it will then be set either in the component's root folder (if it has a functional meaning), or at the root of the functional folder in a dedicated subfolder. +* A component shared among different blocks and hosted in the same functional folder should be placed in a shared folder under the functional one. * Avoid creating useless intermediate folder: * A component with only a presenter and no container should not have a presenter folder * A functional area containing only one block should not have a sub-folder for it @@ -125,29 +89,26 @@ passengers/ ``` app/src/ - components/ - my-complex-area/ - my-complex-component/ - container/ - contracts/ - directives/ - presenter/ - sub-components/ - my-sub-component/ - container/ - presenter/ - my-simple-component/ - shared/ - my-shared-component-in-area/ - container/ - presenter/ - my-simple-area/ - container/ - presenter/ - shared/ - my-shared-component-in-lib/ - container/ - presenter/ - elements/ - my-element/ + components/ + my-complex-area/ + my-complex-component/ + container/ + contracts/ + presenter/ + sub-components/ + my-sub-component/ + my-simple-component/ + shared/ + my-shared-component-in-my-complex-area/ + container/ + presenter/ + my-simple-area/ + container/ + presenter/ + shared/ + my-shared-component-in-app/ + container/ + presenter/ + elements/ + my-element/ ``` diff --git a/docs/components/FIXTURES.md b/docs/components/FIXTURES.md index 203a8d29d2..df3b09070d 100644 --- a/docs/components/FIXTURES.md +++ b/docs/components/FIXTURES.md @@ -160,3 +160,10 @@ const radioGroup = myElement.queryAll(".my-radios", O3rRadioElement, O3rRadioGro cont selectedRadioElement: O3rRadioElement = radioGroup.getSelectedItem(); ``` + +## Naming convention + +| Attribute | Pattern | +| --------------------- | ------------ | +| **Fixture file name** | *.fixture.ts | +| **Fixture name** | *Fixture | diff --git a/docs/components/INTRODUCTION.md b/docs/components/INTRODUCTION.md new file mode 100644 index 0000000000..2e14666609 --- /dev/null +++ b/docs/components/INTRODUCTION.md @@ -0,0 +1,75 @@ +# Component introduction + +A component refers to a modular, reusable piece of code that encapsulates specific functionality, styling, and behavior within a user interface (UI). Components are commonly used to build dynamic and interactive web applications, allowing developers to break down complex user interfaces into smaller, manageable parts. + +## How to generate a component + +```shell +ng g component [--project-name ] +``` + +## Structure +Below you can see the basic files generated for a component (more files can be generated depending on the activated options): +- `component-name.component.ts` will contain the logic of the component +- `component-name.spec.ts` will contain component unit tests +- `component-name.style.scss` will contain the styling of the component +- `component-name.template.html` will contain the structure of the component + +> [!NOTE] +> By convention, file names must be written in kebab-case + + +## Component class +Otter components are Angular components with Otter-specific information provided through the `@O3rComponent` decorator. +It will be used to extract metadata or for debugging purpose. + +```typescript +@O3rComponent({ + componentType: 'Component' +}) +@Component({ + selector: 'o3r-component-name', + standalone: true, + templateUrl: './component-name.template.html', + styleUrls: ['./component-name.style.scss'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ComponentNameComponent {} +``` + +> [!NOTE] +> By convention, class names must be written in PascalCase and variable names in camelCase. + +### Component type +The object passed to the `@O3rComponent` decorator includes the component type, which can be: +- `Page`: a component that displays an application route +- `Block`: a component that handles a functional area +- `ExposedComponent`: a component that needs to be exposed in your CMS +- `Component`: a component that does not need to be exposed in your CMS and that does not fit the others categories + +Example: +![Component type example](../../assets/schemas/component-type-example.png) + +## Runtime debugging + +The Otter framework provides an [Otter Chrome Extension](https://chrome.google.com/webstore/detail/otter-devtools/aejabgendbpckkdnjaphhlifbhepmbne) to help debug an Otter application. +To enable the communication between your application and the Chrome Extension you can follow this [documentation](../dev-tools/chrome-devtools.md). + +## Next steps + +To provide [UI Test Fixtures](https://en.wikipedia.org/wiki/Test_fixture#Software) capabilities, you can refer to the [fixtures documentation](./FIXTURES.md). + +In case you need to handle different UI flavors or to share a flavor with different logics, we recommend to use the [container / presenter](./CONTAINER_PRESENTER.md) patterns. + +Different kind of customization could be applied to a component: + +* [Configuration](../configuration/OVERVIEW.md) +* [Localization](../localization/LOCALIZATION.md) +* [Styling](../styling/THEME.md) +* [Design token](../design/TECHNICAL_DOCUMENTATION.md) +* [Analytics](../analytics/ANALYTICS.md) + +In case you need to replace a component at runtime, you can have a look at the [component replacement](./COMPONENT_REPLACEMENT.md) mechanism. + +In case you need to integrate dynamic HTML elements (with a basic rendering system) at a predefined position in the application, you can have a look at the [placeholder](./PLACEHOLDERS.md) mechanism. diff --git a/docs/components/NAMING_CONVENTION.md b/docs/components/NAMING_CONVENTION.md deleted file mode 100644 index a5b4e1d4a8..0000000000 --- a/docs/components/NAMING_CONVENTION.md +++ /dev/null @@ -1,46 +0,0 @@ -# Naming convention -Naming convention is here to help you set your variable names in a common manner in order to keep code coherence and -readability - -## File names - -File names must be written in Kebab case - -Depending on container or presenter context, your file names should be suffixed with ``` -cont ``` or ``` -pres ``` -.
-More details are available in [Component structure documentation](./COMPONENT_STRUCTURE.md) - -You will find below the patterns to be followed for file names in the different context: -* component: ``` ${name}.component.ts ``` -* configuration: ``` ${name}.config.ts ``` -* context: ``` ${name}.context.ts ``` -* fixture: ``` ${name}.fixture.ts ``` -* integration test: ``` ${name}.int-spec.ts ``` -* module: ``` ${name}.module.ts ``` -* template: ``` ${name}.template.html ``` -* barrel: ``` index.ts ``` -* style: ``` ${name}.style.scss ``` -* theme: ``` ${name}.style.theme.scss ``` -* readme: ``` README.md ``` -* unit test: ``` ${name}.spec.ts ``` - -## Class names - -Class names must be written in Pascal case. - -You will find below the patterns to be followed for components class names in the different context: -* container: ``` ${name}ContComponent ``` -* presenter: ``` ${name}PresComponent ``` -* configuration: ``` ${name}(Cont | Pres)Config ``` -* context: ``` ${name}(Cont | Pres)ContextInput ``` ``` ${name}(Cont | Pres)ContextOuput ``` ``` ${name}(Cont | Pres) -Context ``` -* fixture: ``` ${name}(Cont | Pres)Fixture ``` -* module: ``` ${name}(Cont | Pres)Module ``` - -## Variable names - -Variable names must be written in Camel case. - -You will find below the patterns to be followed for variable names in the different context: -* For templateRef: ``` ${targeted component class name without Component suffix}(Cont | Pres)Template ``` -* For config: ``` ${targeted component class name without Component suffix}(Cont | Pres)Config ``` diff --git a/docs/configuration/CONFIGURATION_SUPPORTED_EXTRACTOR.md b/docs/configuration/CONFIGURATION_SUPPORTED_EXTRACTOR.md index 7b345b0086..97314ed6df 100644 --- a/docs/configuration/CONFIGURATION_SUPPORTED_EXTRACTOR.md +++ b/docs/configuration/CONFIGURATION_SUPPORTED_EXTRACTOR.md @@ -10,7 +10,7 @@ The Component Extractor is accessible via this [Angular CLI builder](https://ang First, define the file names of the package metadata in the `package.json` of the library/application where you run the extractor. When the extractor is run in a project, it will use these file names to name the output files of the extraction. In case you want to compile the metadata of the project with its dependencies (generally for an application that has libraries with their own metadata as well), the extractor will need to find the metadata for each dependency. -In that case, the extractor will search for these file names in the `package.json` file of each library (in the `node_modules`) +In that case, the extractor will search for these file names in the `package.json` file of each library (in the `node_modules`) in order to concatenate the file's metadata with the metadata of other libraries and the application's metadata. In the `package.json` of the library: diff --git a/docs/configuration/OVERVIEW.md b/docs/configuration/OVERVIEW.md index f0d591a65a..756c6e1a20 100644 --- a/docs/configuration/OVERVIEW.md +++ b/docs/configuration/OVERVIEW.md @@ -72,7 +72,7 @@ A component will have to handle different types of configurations. ## How to set up the configuration service We support two ways of setting up the configuration service (`ConfigurationBaseService`). It can be at the bootstrap of the -application for a static configuration or at any time during application execution for a dynamic configuration. +application for a static configuration or at any time during application execution for a dynamic configuration. ### Static configuration (override) @@ -89,7 +89,7 @@ components when they are instantiated. ### Dynamic configuration -- The default configuration is extracted by __@o3r/components:extractor__ and bundled in a JSON file. You may have a CMS (your own or a plugin) +- The default configuration is extracted by __@o3r/components:extractor__ and bundled in a JSON file. You may have a CMS (your own or a plugin) that would take this configuration metadata as an input. For example, if you have a CMS plugin, you can expose the JSON file in this plugin. - In the configuration UI, the Business Analyst will modify the configuration of components which will be exposed (in the server) as dynamic content of the app. @@ -170,7 +170,7 @@ The configuration should extend the interface of the configuration that is suppo > The Otter VSCode extension offers a command to add configuration to an existing component. To do so, right-click a component file (ending with *.component.ts), > select "Enrich Otter component", then the option "Add configuration to component". -It can also contain nested configurations which need to extend `NestedConfiguration`. +It can also contain nested configurations which need to extend `NestedConfiguration`. This interface is part of the @o3r/core package, with only primitive types allowed inside (string | boolean | number) or an array of primitive types. OPTIONAL types are NOT supported and will be ignored by the extractor. @@ -445,7 +445,6 @@ export class MyComponent implements DynamicConfigurableWithSignal { public readonly configSignal = configSignal(this.config, MY_CONFIG_ID, MY_DEFAULT_CONFIG, this.configurationService); } ``` - ### Application To use the configuration mechanism, the first step is to inject the configuration module into our application module. diff --git a/docs/forms/FORM_STRUCTURE.md b/docs/forms/FORM_STRUCTURE.md index 8ca948f510..7f81c93967 100644 --- a/docs/forms/FORM_STRUCTURE.md +++ b/docs/forms/FORM_STRUCTURE.md @@ -24,7 +24,7 @@ Angular provides two approaches for writing the forms, [template-driven forms](h This documentation will help you with some best practices to be used at the build of Angular reactive forms components in Otter context. -## [Container/presenter](../components/COMPONENT_STRUCTURE.md) and reactive forms +## [Container/presenter](../components/CONTAINER_PRESENTER.md) and reactive forms Container/presenter architecture was put in place to ensure the best re-usability/sharing ### Form creation in container or in presenter? @@ -63,7 +63,6 @@ This case includes the simple case plus the display of a messages panel containi * easily get the errors propagated by the presenter We prefer to use the __formControl__ rather than __ngModel__ because we can easily listen to the valueChanges or status changes of the presenter form. -Another constraint is that it's easier to identify the container context for the CMS, with one implementation (See [Component Structure](../components/COMPONENT_STRUCTURE.md) for details about the component context). ### Component creation @@ -134,7 +133,7 @@ ngOnInit() { } ``` - * Register the form control in the template context to be recognized if we change the presenter. See [COMPONENT_STRUCTURE](../components/COMPONENT_STRUCTURE.md) for details about the template context. + * Register the form control in the template context to be recognized if we change the presenter. See [the component replacement documentation](../components/COMPONENT_REPLACEMENT.md) for details about the template context. ```typescript // in container class diff --git a/docs/localization/LOCALIZATION.md b/docs/localization/LOCALIZATION.md index 75a317a148..cc4311f85f 100644 --- a/docs/localization/LOCALIZATION.md +++ b/docs/localization/LOCALIZATION.md @@ -142,7 +142,7 @@ Now we are ready to localize the components of the application. ### How to generate localization files for a component -#### Generate a localized component +#### Generate a localized component You can directly generate a localized component with the following command: ```shell @@ -172,7 +172,7 @@ under the `schematics` property, like this: > ng add @o3r/localization > ``` -#### Add localization to an existing component +#### Add localization to an existing component You can also localize a component later with: ```shell @@ -253,7 +253,7 @@ More details on how to do this in the [documentation](https://github.com/Amadeus #### Translation file (`*.translation.ts`) -The translation file is used to define the localization variables used by the component template. +The translation file is used to define the localization variables used by the component template. It typically defines an interface which extends `Translation` from `@o3r/core` with all possible variable names used by your component template. It also exports a constant (`translations`) that satisfies the above contract. The values for each property are localization keys (real keys from the localization bundle). @@ -422,7 +422,7 @@ Now we can start using pipes: ``` > [!NOTE] -> A locale parameter can be added to the pipe, such as the following: +> A locale parameter can be added to the pipe, such as the following: > ```html >

{{today | date: 'fullDate' : '' : currentLanguage()}}

> ``` @@ -656,10 +656,10 @@ return { * `en-CA` **fallbacks to** `en-US`, as direct mapping available in fallback locales map. * `de-CH` **fallbacks to** `ar-AR`, as direct mapping available in fallback locales map. -* `de-AT` **fallbacks to** `fr-FR`, as language mapping available in fallback locales map. +* `de-AT` **fallbacks to** `fr-FR`, as language mapping available in fallback locales map. * `zh-CN` **fallbacks to** `en-GB`, as language mapping available in fallback locales map. * `en-AU` **fallbacks to** `en-GB`, as fallback locales mapping unavailable, first nearest language available in supported locales. -* `fr-BE` **fallbacks to** `fr-FR`, as fallback locales mapping unavailable, first nearest language available in supported locales. +* `fr-BE` **fallbacks to** `fr-FR`, as fallback locales mapping unavailable, first nearest language available in supported locales. * `bn-BD` **fallbacks to** `ar-AR`, as it is the default fallback. ## Scenario 2: Fallback based on `supportedLocales` diff --git a/docs/styling/THEME.md b/docs/styling/THEME.md index c26ac4f4af..2c582297f0 100644 --- a/docs/styling/THEME.md +++ b/docs/styling/THEME.md @@ -3,42 +3,40 @@ ## About the theme The theme consists in a set of properties (border, radius, shadow, colors) that are consistent throughout the application. -If the airline changes one of those properties, it will impact all the elements that rely upon it. For example, if -in the theme, a shadow color is defined, the airline can override it and impact all the components with shadows. +Let's assume the customization of your application is outsourced to a client. +If the client changes one of those properties, it will impact all the elements that rely upon it. For example, if +in the theme, a shadow color is defined, the client can override it and impact all the components with shadows. The theme properties can be split according to the following concerns: -* **Are the properties highly customizable?** This concerns the colours palette used within the components. The airline +* **Are the properties highly customizable?** This concerns the colours palette used within the components. The client **will** necessarily have to modify them to follow their brand. * **Are the properties mostly customizable?** This concerns a set of properties and variables such as the shadows, background and foreground that might be custom to change the general look and feels of the application. -For instance, if the airline wants to impact the shadow colors on a darker theme, the border radius on the buttons, on +For instance, if the client wants to impact the shadow colors on a darker theme, the border radius on the buttons, on the list or on the different containers. -* **Are these changes specific to a component?** If the airline changes are really specific and impact the product +* **Are these changes specific to a component?** If the client changes are really specific and impact the product designs, this will be done on component level. This is not part of the theme customization. For more information on the Amadeus palettes you can refer to [Amadeus Color Guidelines](https://github.com/AmadeusITGroup/otter/blob/main/packages/%40o3r/styling/scss/theming/palettes/_amadeus.scss). ## Create your theme -Find below the process to generate your own theme. RefX is used here as an example, you can replace it with any other theme. +You can find below the process to generate your own theme. -### Generate the RefX theme variables +### Generate your own theme variables Create a new theme generator in your repository. It shall generate a map of properties that will be used -directly in the components stylesheets. +directly in the component's stylesheets. The generator shall take a map of overridden properties in order to allow different variations of the theme. The theme properties can be computed from private variables. Your private variables are not part of your theme and should not be used within the components. There is no guarantee they will always be available in your theme. If you find the theme properties lacking, please update the generator and do not rely upon `$overridden-properties`. -**Note**: The RefX theme generator is in the otter library to provide a complete theme for all the new application -(e.g. Blank App). This is the default theme. Any new theme, will be in the repository using it. - **Note**: Your theme generator should always extend the basic generator in the otter library: -`generate-theme-variables`. This generator sole purpose is to make sure all the mandatory theme properties are -available with a default value each. It is up to the theme to override it with its own variables. +`generate-theme-variables`. The sole purpose of this generator is to make sure all the mandatory theme properties are +available with a default value for each. It is up to the theme to override it with its own variables. ```scss // Generate a map of theme variables for your application and override them with the customer's properties @@ -60,7 +58,7 @@ available with a default value each. It is up to the theme to override it with i $private: map_merge($private-variables-default, $overridden-properties); // Properties that are specific to the application - $refx-variables: ( + $own-variables: ( border-style: get-mandatory($private, 'line-style'), border-color: get-mandatory($private, 'graphical-line'), separator-style: get-mandatory($private, 'line-style'), @@ -104,29 +102,29 @@ functions returns a map with the following entries: There is no direct way to override the values within the theme but to call `map_merge`. Material has not provided a way to create a consistent theme from a text color and a background color. -This has to be done on the refex repository via an override function. - ```scss +@use '@o3r/styling' as o3r; + @function _override-mat-theme($mat-theme, $application-variables) { - $mat-foreground: get-mandatory($mat-theme, 'foreground'); - $mat-background: get-mandatory($mat-theme, 'background'); + $mat-foreground: o3r.get-mandatory($mat-theme, 'foreground'); + $mat-background: o3r.get-mandatory($mat-theme, 'background'); $foreground-override: ( - divider: get-mandatory($application-variables, 'separator-color'), - dividers: get-mandatory($application-variables, 'separator-color'), - elevation: get-mandatory($application-variables, 'shadow-color'), - hint-text: get-mandatory($application-variables, 'text'), - secondary-text: get-mandatory($application-variables, 'text'), - icon: get-mandatory($application-variables, 'text'), - icons: get-mandatory($application-variables, 'text'), - text: get-mandatory($application-variables, 'text') + divider: o3r.get-mandatory($application-variables, 'separator-color'), + dividers: o3r.get-mandatory($application-variables, 'separator-color'), + elevation: o3r.get-mandatory($application-variables, 'shadow-color'), + hint-text: o3r.get-mandatory($application-variables, 'text'), + secondary-text: o3r.get-mandatory($application-variables, 'text'), + icon: o3r.get-mandatory($application-variables, 'text'), + icons: o3r.get-mandatory($application-variables, 'text'), + text: o3r.get-mandatory($application-variables, 'text') ); $background-override: ( - background: get-mandatory($application-variables, 'panel-background'), - hover: get-mandatory($application-variables, 'panel-hover'), - card: get-mandatory($application-variables, 'panel-background'), - dialog: get-mandatory($application-variables, 'dialog-background') + background: o3r.get-mandatory($application-variables, 'panel-background'), + hover: o3r.get-mandatory($application-variables, 'panel-hover'), + card: o3r.get-mandatory($application-variables, 'panel-background'), + dialog: o3r.get-mandatory($application-variables, 'dialog-background') ); @return map_merge( @@ -263,8 +261,8 @@ $highlight: mat.$mat-pink, A200, A100, A400; // Override the amadeus theme: -$candy-app-primary: otter-theme.define-palette(mat.$mat-indigo); -$candy-app-accent: otter-theme.define-palette(mat.$mat-pink, A200, A100, A400); +$candy-app-primary: mat.palette(mat.$mat-indigo); +$candy-app-accent: mat.palette(mat.$mat-pink, A200, A100, A400); // Generate Meta Theme $candy-meta-theme: otter-theme.generate-otter-theme($primary: $candy-app-primary, $highlight: $candy-app-accent); @@ -300,10 +298,10 @@ Note that nothing prevents you from overriding both the palettes and the theme v ```scss // overrides -$override-refx-theme: (panel-background: #AAA); +$override-original-theme: (panel-background: #AAA); // Include the default theme styles. -$meta-theme: generate-app-theme($override: $override-refx-theme); +$meta-theme: generate-app-theme($override: $override-original-theme); ``` > [!IMPORTANT] @@ -311,29 +309,6 @@ $meta-theme: generate-app-theme($override: $override-refx-theme); #### Architecture -### Customize the material elements - -If a material component css happens not to fit with the application theme or not to be customizable enough for the -implementations, it is still possible to override it via mixins. - -Otter library provides the mixins that can be used to override some css properties in the material design components. -They are available in the `@o3r/styling`. - -```scss -//button-override-mixin - -@mixin app-button-theme($theme) { - .mat-button-selector { - property-to-override: get-theme-property($theme, 'property-to-override'); - } -} -``` - -**Caution**: Since the mixin can easily break after a material design update, you should rely on them as little as -possible and only in an airline implementations, never directly in a library (e.g. RefX library). -You can include them directly in your global css if you want to impact all the material component within the -application or directly in a module for a more local customization. - ### Style your components #### Variables diff --git a/packages/@o3r/analytics/README.md b/packages/@o3r/analytics/README.md index dd235258c7..10054671bc 100644 --- a/packages/@o3r/analytics/README.md +++ b/packages/@o3r/analytics/README.md @@ -26,7 +26,7 @@ ng add @o3r/analytics ## Generators -Otter framework provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter framework provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). | Schematics | Description | How to use | | -------------------------- | -------------------------------------------------------------- | --------------------------------- | diff --git a/packages/@o3r/components/schematics/ng-add/index.ts b/packages/@o3r/components/schematics/ng-add/index.ts index 339d169dc5..4f72852416 100644 --- a/packages/@o3r/components/schematics/ng-add/index.ts +++ b/packages/@o3r/components/schematics/ng-add/index.ts @@ -75,7 +75,7 @@ function ngAddFn(options: NgAddSchematicsSchema): Rule { ]); context.logger.info(`The package ${depsInfo.packageName!} comes with a debug mechanism`); - context.logger.info('Get more information on the following page: https://github.com/AmadeusITGroup/otter/tree/main/docs/components/COMPONENT_STRUCTURE.md#Runtime-debugging'); + context.logger.info('Get more information on the following page: https://github.com/AmadeusITGroup/otter/tree/main/docs/components/INTRODUCTION.md#Runtime-debugging'); return () => rule(tree, context); }; diff --git a/packages/@o3r/configuration/schematics/configuration-to-component/index.ts b/packages/@o3r/configuration/schematics/configuration-to-component/index.ts index 46debca05f..1353ae8fc7 100644 --- a/packages/@o3r/configuration/schematics/configuration-to-component/index.ts +++ b/packages/@o3r/configuration/schematics/configuration-to-component/index.ts @@ -276,9 +276,9 @@ export function ngAddConfigFn(options: NgAddConfigSchematicsSchema): Rule { addCommentsOnClassProperties( newMembers, { - config: 'Input configuration to override the default configuration of the component', + config: '@inheritDoc', dynamicConfig: 'Dynamic configuration based on the input override configuration and the configuration service if used by the application', - config$: 'Configuration stream based on the input and the stored configuration' + config$: '@inheritDoc' } ); @@ -387,8 +387,8 @@ export function ngAddConfigFn(options: NgAddConfigSchematicsSchema): Rule { addCommentsOnClassProperties( newMembers, { - config: 'Input configuration to override the default configuration of the component', - configSignal: 'Configuration signal based on the input and the stored configuration' + config: '@inheritDoc', + configSignal: '@inheritDoc' } ); diff --git a/packages/@o3r/core/README.md b/packages/@o3r/core/README.md index e0819cdac9..59a7646b01 100644 --- a/packages/@o3r/core/README.md +++ b/packages/@o3r/core/README.md @@ -61,7 +61,7 @@ Then uncomment the following lines in the `src/styles.scss` file to apply the Ot ## Generators -Otter framework provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter framework provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). ### Item generators diff --git a/packages/@o3r/core/src/core/interfaces/configuration.ts b/packages/@o3r/core/src/core/interfaces/configuration.ts index 625491f755..8c27334c27 100644 --- a/packages/@o3r/core/src/core/interfaces/configuration.ts +++ b/packages/@o3r/core/src/core/interfaces/configuration.ts @@ -39,12 +39,12 @@ export interface CustomConfig = Partial { /** - * Configuration override + * Configuration override by Angular input mechanism */ config: Partial | undefined; /** - * Configuration stream + * Configuration stream based on the input and the stored configuration */ config$: Observable; } @@ -54,12 +54,12 @@ export interface DynamicConfigurable { */ export interface DynamicConfigurableWithSignal { /** - * Configuration override + * Configuration override by Angular input mechanism */ config: InputSignal | undefined>; /** - * Configuration signal + * Configuration signal based on the input and the stored configuration */ configSignal: Signal; } diff --git a/packages/@o3r/design/README.md b/packages/@o3r/design/README.md index 5dc8b069d0..3885c59f2b 100644 --- a/packages/@o3r/design/README.md +++ b/packages/@o3r/design/README.md @@ -22,7 +22,7 @@ ng add @o3r/design ## Generators -Otter Design module provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter Design module provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). | Schematics | Description | How to use | | ------------ | ------------------------------------------------------- | -------------------- | @@ -31,7 +31,7 @@ Otter Design module provides a set of code generators based on [angular schemati ## Builders -Otter Design module provides a set of builders based on [angular builders](https://angular.io/guide/cli-builder). +Otter Design module provides a set of builders based on [Angular builders](https://angular.io/guide/cli-builder). ### generate-css diff --git a/packages/@o3r/rules-engine/README.md b/packages/@o3r/rules-engine/README.md index 3c78059405..b5dcbd760b 100644 --- a/packages/@o3r/rules-engine/README.md +++ b/packages/@o3r/rules-engine/README.md @@ -65,7 +65,7 @@ Several examples of the rules engine usage are available on the following links: ## Generators -Otter framework provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter framework provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). | Schematics | Description | How to use | |---------------------------|---------------------------------------------------------------|----------------------------------| diff --git a/packages/@o3r/styling/README.md b/packages/@o3r/styling/README.md index f7c21ed258..b30add3879 100644 --- a/packages/@o3r/styling/README.md +++ b/packages/@o3r/styling/README.md @@ -29,7 +29,7 @@ Find more information in the [documentation](https://github.com/AmadeusITGroup/o ## Generators -Otter framework provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter framework provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). | Schematics | Description | How to use | | -------------------------- | -------------------------------------------------------------- | --------------------------------- | diff --git a/packages/@o3r/testing/README.md b/packages/@o3r/testing/README.md index 20e406f9ff..414a7fcc3b 100644 --- a/packages/@o3r/testing/README.md +++ b/packages/@o3r/testing/README.md @@ -29,7 +29,7 @@ Find more information in the [documentation](https://github.com/AmadeusITGroup/o ## Generators -Otter framework provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter framework provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). | Schematics | Description | How to use | | -------------------------- | ----------------------------------------------------------------------------- | --------------------------------- | diff --git a/packages/@o3r/third-party/README.md b/packages/@o3r/third-party/README.md index 8674b93b07..2101d081f5 100644 --- a/packages/@o3r/third-party/README.md +++ b/packages/@o3r/third-party/README.md @@ -28,7 +28,7 @@ ng add @o3r/third-party ## Generators -Otter framework provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter framework provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). | Schematics | Description | How to use | | --------------------- | ------------------------------------------------------------ | --------------------------- | diff --git a/packages/@o3r/workspace/README.md b/packages/@o3r/workspace/README.md index c0b88ba0b8..f90caca2b8 100644 --- a/packages/@o3r/workspace/README.md +++ b/packages/@o3r/workspace/README.md @@ -14,7 +14,7 @@ This packages provides several [Schematics](#schematics) and [CLIs](#scripts) us ## Schematics -Otter framework provides a set of code generators based on [angular schematics](https://angular.io/guide/schematics). +Otter framework provides a set of code generators based on [Angular schematics](https://angular.io/guide/schematics). | Schematics | Description | How to use | | -------------------------- | ----------------------------------------------------------------------------- | --------------------------------- |