Commit 3d8f6638 authored by Thibault Ehrhart's avatar Thibault Ehrhart

Initial commit

"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "asrael"
"apps": [
"root": "src",
"outDir": "dist",
"assets": [
"index": "index.html",
"main": "main.ts",
"serviceWorker": true,
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"hmr": "environments/environment.hmr.ts",
"prod": "environments/"
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
"lint": [
"project": "src/",
"exclude": "**/node_modules/**"
"project": "src/tsconfig.spec.json",
"exclude": "**/node_modules/**"
"project": "e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
"test": {
"karma": {
"config": "./karma.conf.js"
"defaults": {
"styleExt": "scss",
"component": {}
# Editor configuration, see
root = true
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
max_line_length = 120
max_line_length = off
trim_trailing_whitespace = false
# See for more about ignoring files.
# Compiled output
# Dependencies
# Cordova
# IDEs and editors
# IDE - VSCode
# Maven
# Misc
# E2E
# System Files
"tagname-lowercase": false,
"attr-lowercase": false,
"attr-value-double-quotes": true,
"tag-pair": true,
"spec-char-escape": true,
"id-unique": true,
"src-not-empty": true,
"attr-no-duplication": true,
"title-require": true,
"tag-self-close": true,
"head-script-disabled": true,
"doctype-html5": true,
"id-class-value": "dash",
"style-disabled": true,
"inline-style-disabled": true,
"inline-script-disabled": true,
"space-tab-mixed-disabled": "true",
"id-class-ad-disabled": true,
"attr-unsafe-chars": true
"extends": ["stylelint-config-standard", "stylelint-config-recommended-scss"],
"rules": {
"font-family-name-quotes": "always-where-recommended",
"function-url-quotes": [
"except": ["empty"]
"selector-attribute-quotes": "always",
"string-quotes": "double",
"max-nesting-depth": 3,
"selector-max-compound-selectors": 3,
"selector-max-specificity": "0,3,2",
"declaration-no-important": true,
"at-rule-no-vendor-prefix": true,
"media-feature-name-no-vendor-prefix": true,
"property-no-vendor-prefix": true,
"selector-no-vendor-prefix": true,
"value-no-vendor-prefix": true,
"no-empty-source": null,
"selector-class-pattern": "[a-z-]+",
"selector-id-pattern": "[a-z-]+",
"selector-max-id": 0,
"selector-no-qualifying-type": true,
"selector-max-universal": 0,
"selector-pseudo-element-no-unknown": [
"ignorePseudoElements": ["ng-deep"]
"unit-whitelist": ["px", "%", "em", "rem", "vw", "vh", "deg"],
"max-empty-lines": 2,
"max-line-length": 120
"generator-ngx-rocket": {
"version": "3.1.1",
"props": {
"appName": "asrael",
"target": [
"pwa": true,
"ui": "bootstrap",
"auth": false,
"projectName": "asrael",
"packageManager": "npm",
"mobile": []
\ No newline at end of file
# asrael
# Getting started
1. Go to project folder and install dependencies:
npm install
2. Launch development server, and open `localhost:4200` in your browser:
npm start
# Project structure
dist/ web app production build
docs/ project docs and coding guides
e2e/ end-to-end tests
src/ project source code
|- app/ app components
| |- core/ core module (singleton services and single-use components)
| |- shared/ shared module (common components, directives and pipes)
| |- app.component.* app root component (shell)
| |- app.module.ts app root module definition
| |- app-routing.module.ts app routes
| +- ... additional modules and components
|- assets/ app assets (images, fonts, sounds...)
|- environments/ values for various build environments
|- theme/ app global scss variables and theme
|- translations/ translations files
|- index.html html entry point
|- main.scss global style entry point
|- main.ts app entry point
|- polyfills.ts polyfills needed by Angular
+- test.ts unit tests entry point
reports/ test and coverage reports
proxy.conf.js backend proxy configuration
# Main tasks
Task automation is based on [NPM scripts](
Task | Description
`npm start` | Run development server on `http://localhost:4200/`
`npm run build [-- --env=prod]` | Lint code and build web app for production (with [AOT]( in `dist/` folder
`npm test` | Run unit tests via [Karma]( in watch mode
`npm run test:ci` | Lint code and run unit tests once for continuous integration
`npm run e2e` | Run e2e tests using [Protractor](
`npm run lint` | Lint code
`npm run translations:extract` | Extract strings from code and templates to `src/app/translations/template.json`
`npm run docs` | Display project documentation
When building the application, you can specify the target environment using the additional flag `--env <name>` (do not
forget to prepend `--` to pass arguments to npm scripts).
The default build environment is `prod`.
## Development server
Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change
any of the source files.
You should not use `ng serve` directly, as it does not use the backend proxy configuration by default.
## Code scaffolding
Run `npm run generate -- component <name>` to generate a new component. You can also use
`npm run generate -- directive|pipe|service|class|module`.
If you have installed [angular-cli]( globally with `npm install -g @angular/cli`,
you can also use the command `ng generate` directly.
## Additional tools
Tasks are mostly based on the `angular-cli` tool. Use `ng help` to get more help or go check out the
[Angular-CLI README](
# What's in the box
The app template is based on [HTML5](, [TypeScript]( and
[Sass]( The translation files use the common [JSON]( format.
#### Tools
Development, build and quality processes are based on [angular-cli]( and
[NPM scripts](, which includes:
- Optimized build and bundling process with [Webpack](
- [Development server]( with backend proxy and live reload
- Cross-browser CSS with [autoprefixer]( and
- Asset revisioning for [better cache management](
- Unit tests using [Jasmine]( and [Karma](
- End-to-end tests using [Protractor](
- Static code analysis: [TSLint](, [Codelyzer](,
[Stylelint]( and [HTMLHint](
- Local knowledgebase server using [Hads](
#### Libraries
- [Angular](
- [Bootstrap 4](
- [ng-bootsrap](
- [Font Awesome](
- [RxJS](
- [ngx-translate](
- [Lodash](
#### Coding guides
- [Angular](docs/coding-guides/
- [TypeScript](docs/coding-guides/
- [Sass](docs/coding-guides/
- [HTML](docs/coding-guides/
- [Unit tests](docs/coding-guides/
- [End-to-end tests](docs/coding-guides/
#### Other documentation
- [I18n guide](docs/
- [Working behind a corporate proxy](docs/
- [Updating dependencies and tools](docs/
- [Using a backend proxy for development](docs/
- [Browser routing](docs/
"path": ".",
"folder_exclude_patterns": ["dist", "docs", "e2e"],
"follow_symlinks": true
# List of supported browsers, for autoprefixer
# See
Last 2 versions
> 1%
# Backend proxy
Usually when working on a web application you consume data from custom-made APIs.
To ease development with our development server integrating live reload while keeping your backend API calls working,
we also have setup a backend proxy to redirect API calls to whatever URL and port you want. This allows you:
- To develop frontend features without the need to run an API backend locally
- To use a local development server without [CORS]( issues
- To debug frontend code with data from a remote testing platform directly
## How to configure
In the root folder you will find a `proxy.conf.js`, containing the backend proxy configuration.
The interesting part is there:
const proxyConfig = [
context: '/api',
pathRewrite: {'^/api': ''},
target: '',
changeOrigin: true
This is where you can setup one or more proxy rules.
For the complete set of options, see the `http-proxy-middleware`
### Corporate proxy support
To allow external API calls redirection through a corporate proxy, you will also find a `setupForCorporateProxy()`
function in the proxy configuration file. By default, this method configures a corporate proxy agent based on the
`HTTP_PROXY` environment variable, see the [corporate proxy documentation]( for more details.
If you need to, you can further customize this function to fit the network of your working environment.
If your corporate proxy use a custom SSL certificate, your may need to add the `secure: false` option to your
backend proxy configuration.
# Introduction to Angular and modern design patterns
[Angular]( (aka Angular 2, 4, 5...) is a new framework completely rewritten from the ground up,
replacing the now well-know [AngularJS]( framework (aka Angular 1.x).
More that just a framework, Angular should now be considered as a whole *platform* which comes with a complete set of
tools, like its own [CLI](, [debug utilities]( or
[performance tools](
Angular has been around for some time now, but I still get the feeling that it’s not getting the love it deserved,
probably because of other players in the field like React or VueJS. While the simplicity behind these frameworks can
definitely be attractive, they lack in my opinion what is essential when making big, enterprise-grade apps: a solid
frame to lead both experienced developers and beginners in the same direction and a rational convergence of tools,
patterns and documentation. Yes, the Angular learning curve may seems a little steep, but it’s definitely worth it.
## Getting started
#### Newcomer
If you're new to Angular you may feel overwhelmed by the quantity of new concepts to apprehend, so before digging in
this project you may want to start with [this progressive tutorial]( that will guide you
step by step into building a complete Angular application.
#### AngularJS veteran
If you come from AngularJS and want to dig straight in the new version, you may want to take a look at the
[AngularJS vs 2 quick reference](
#### Cheatsheet
Until you know the full Angular API by heart, you may want to keep this
[cheatsheet]( that resumes the syntax and features on a single page at hand.
## Style guide
This project follows the standard [Angular style guide](
More that just coding rules, this style guide also gives advices and best practices for a good application architecture
and is an **essential reading** for starters. Reading deeper, you can even find many explanations for some design
choices of the framework.
## Going deeper
Even though they are not mandatory, Angular was designed for the use of design patterns you may not be accustomed to,
like [reactive programming](#reactive-programming), [unidirectional data flow](#unidirectional-data-flow) and
[centralized state management](#centralized-state-management).
These concepts are difficult to resume in a few words, and despite being tightly related to each other they concern
specific parts of an application flow, each being quite deep to learn on its own.
You will essentially find here a list of good starting points to learn more on these subjects.
#### Reactive programming
You may not be aware of it, but Angular is now a *reactive system* by design.
Although you are not forced to use reactive programming patterns, they make the core of the framework and it is
definitely recommended to learn them if you want to leverage the best of Angular.
Angular uses [RxJS]( to implement the *Observable* pattern.
> An *Observable* is a stream of asynchronous events that can be processed with array-like operators.
##### From promises to observables
While AngularJS used to rely heavily on [*Promises*]($q) to handle
asynchronous events, *Observables* are now used instead in Angular. Even though in specific cases like for HTTP
requests, an *Observable* can be converted into a *Promise*, it is recommended to embrace the new paradigm as it can a
lot more than *Promises*, with way less code. This transition is also explained in the
[Angular tutorial](!%23observables).
Once you have made the switch, you will never look back again.
##### Learning references
- [What is reactive programming?](, explained nicely through a simple
imaged story *(5 min)*
- [The introduction to reactive programming you've been missing](,
the title says it all *(30 min)*
- [Functional reactive programming for Angular 2 developers](,
see the functional reactive programming principles in practice with Angular *(15 min)*
- [RxMarbles](, a graphical representation of Rx operators that greatly help to understand their
#### Unidirectional data flow
In opposition with AngularJS where one of its selling points was two-way data binding which ended up causing a lot of
major headaches for complex applications, Angular now enforces unidirectional data flow.
What does it means? Said with other words, it means that change detection cannot cause cycles, which was one of
AngularJS problematic points. It also helps to maintain simpler and more predictable data flows in applications, along
with substantial performance improvements.
**Wait, then why the Angular documentation have mention of a
[two-way binding syntax](**
If you look closely, the new two-way binding syntax is just syntactic sugar to combine two *one-way* bindings (a
*property* and *event* binding), keeping the data flow unidirectional.
This change is really important, as it was often the cause of performance issues with AngularJS, and it one of the
pillars enabling better performance in new Angular apps.
While Angular tries to stay *pattern-agnostic* and can be used with conventional MV* patterns, it was designed with
reactive programming in mind and really shines when used with reactive data flow patterns like
[Flux]( or
#### Centralized state management
As applications grow in size, keeping track of the all its individual components state and data flows can become
tedious, and tend to be difficult to manage and debug.
The main goal of using a centralized state management is to make state changes *predictable* by imposing certain
restrictions on how and when updates can happen, using *unidirectional data flow*.
This approach was first made popular with React with introduction of the
[Flux]( architecture. Many libraries emerged then
trying to adapt and refine the original concept, and one of these gained massive popularity by providing a simpler,
elegant alternative: [Redux](
Redux is at the same time a library (with the big *R*) and a design pattern (with the little *r*), the latter being
framework-agnostic and working very well with Angular.
The *redux* design pattern is based on these [3 principles](
- The application state is a *single immutable* data structure
- A state change is triggered by an *action*, an object describing what happened
- Pure functions called *reducers* take the previous state and the next action to compute the new state
The core concepts behind these principles are nicely explained in
[this example]( *(3 min)*.
##### Which library to use?
You can make Angular work with any state management library you like, but your best bet would be to use
[@ngrx/store]( It works the same as the popular [Redux]( library,
but with a tight integration with Angular and [RxJS](, with some nice additional developer
Here are some resources to get started:
- [Build a better Angular 2 application with redux and ngrx](,
a nice tutorial for @ngrx/store *(30 min)*
- [Comprehensive introduction to @ngrx/store](, an in-depth
walkthrough to this library usage in Angular *(60 min)*
##### When to use it?
You may have noticed that the starter template does not include a centralized state management system out of the box.
Why is that? Well, while there is many benefits from using this pattern, the choice is ultimately up to your team and
what you want to achieve with your app.
Keep in mind that using a single centralized state for your app introduces a new layer a complexity
[that might not be needed](, depending of your
## Optimizing performance
While the new Angular version resolves by design most of the performance issues that could be experienced with
AngularJS, there is always room for improvements. Just keep in mind that delivering an app with good performance is
often a matter of common sense and sane development practices.
Here is [a list of key points]( to check for in your app to
make sure you deliver the best experience to your customers.
After going through the checklist, make sure to also run an audit of your page through
[**Lighthouse**](, the latest Google tool that gives you meaningful
insight about your app performance, accessibility, mobile compatibility and more.
# End-to-end tests coding guide
End-to-end (E2E for short) tests are meant to test the behavior of your application, from start to finish.
While unit tests are the first choice for catching bugs and regression on individual components, it is a good idea to
complement them with test cases covering the integration between the individual components, hence the need for E2E
These tests use [Protractor](, which is a framework built for Angular on top of
[Selenium]( to control browsers and simulate user inputs.
[Jasmine]( is used as the base test framework.
## Good practices
- Avoid whenever possible inter-dependencies between your E2E tests
- Run E2E tests on your continuous integration server against different browsers
- If you use an Agile methodology, cover each user story acceptance factors with an E2E test
## Page objects
E2E tests should follow the *[Page Object](* pattern.
#### What is a page object?
A page object:
- Models the objects on a page under test:
* *Properties* wrap page elements
* *Methods* wrap code that interacts with the page elements
- Simplifies the test scripts
- Reduces the amount of duplicated code
If the UI changes, the fix only needs to be applied in one place.
#### How to define a page object
// login.po.ts
import { browser, element, by } from 'protractor';
export class LoginPage {
emailInput = element(by.css('input[name=^"email"]'));
passwordInput = element(by.css('input[name=^"password"]'));
loginButton = element(by.css('button[(click)^="login"]'));
registerButton = element(by.css('button[(click)^="register"]'));
navigateTo() {
return browser.get('/');
getGreetingText() {
return element(by.css('.greeting')).getText();
#### How to use a page object
// login.e2e-spec.ts
import { LoginPage } from './login.po';
describe('Login', () => {
let page: LoginPage ;
beforeEach(() => {
page = new LoginPage();
it('should navigate to the register page when the register button is clicked', () => {;
it('should allow a user to log in', () => {
expect(page.getGreetingText()).toContain('Welcome, Test User');
## Credits
Parts of this guide were freely inspired by this
# HTML coding guide
## Naming conventions
- Everything should be named in `kebab-case` (lowercase words separated with a `-`): tags, attributes, IDs, etc,
**except for everything bound to Angular** such variables, directives or events which should be in `camelCase`
- File names should always be in `kebab-case`
## Coding rules
- Use HTML5 doctype: `<!doctype html>`
- Use HTML [semantic elements](
- Use double quotes `"` around attribute values in tags
- Use a new line for every block, list, or table element, and indent every such child element
- Clearly Separate structure (HTML) from presentation (CSS) from behavior (JavaScript):
* Never use inline CSS or JavaScript
* Keep any logic out of the HTML
- `type` attribute for stylesheets and script tags should be omitted
## Common pitfalls
- **Block**-type tags cannot be nested inside **inline**-type tags: a `<div>` tag cannot be nested in a `<span>`.
This rule also applies regarding the `display` value of an element.
- HTML is **not** XML: empty tags cannot be self-closing and will result in improper results
* `<div/>` will be interpreted as a simple `<div>` with