diff --git a/src/app/shared/filter/checkbox-filter/checkbox-filter.css b/src/app/shared/filter/checkbox-filter/checkbox-filter.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/shared/filter/checkbox-filter/checkbox-filter.html b/src/app/shared/filter/checkbox-filter/checkbox-filter.html
new file mode 100644
index 0000000..b6d06dc
--- /dev/null
+++ b/src/app/shared/filter/checkbox-filter/checkbox-filter.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Tout sélectionner
+
+
+ {{data[propertyValueName]}}
+ {{data}}
+
+
+
\ No newline at end of file
diff --git a/src/app/shared/filter/checkbox-filter/checkbox-filter.ts b/src/app/shared/filter/checkbox-filter/checkbox-filter.ts
new file mode 100644
index 0000000..e6ff222
--- /dev/null
+++ b/src/app/shared/filter/checkbox-filter/checkbox-filter.ts
@@ -0,0 +1,120 @@
+import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from "@angular/core";
+
+import { SelectedElement } from "@shared/filter/selected-element";
+
+
+
+
+@Component({
+ selector: "checkbox-filter",
+ templateUrl: "./checkbox-filter.html",
+ styleUrls: ["./checkbox-filter.css"]
+})
+export class CheckboxFilterComponent implements OnInit, OnChanges {
+
+ /**
+ * Liste des éléments sélectionnés
+ */
+ elementsSelected: Array = [];
+
+ /**
+ * Booléen permettant de determiner si la propriété "propertyValueName" contient une valeur ou non
+ */
+ isPropertyValueName: boolean;
+
+ /**
+ * Coche toutes les cases à cocher
+ */
+ @Input() checkedAll: boolean;
+
+ /**
+ * Source de données
+ */
+ @Input() dataSource : Array;
+
+ /**
+ * Nom de la propriété contenant la valeur à afficher
+ */
+ @Input() propertyValueName: string;
+
+ /**
+ * Booléen permettant de savoir si toutes les cases sont cochées ou non
+ */
+ @Output() isSelectedAllEvent = new EventEmitter();
+
+ /**
+ * Elément sélectionné
+ */
+ @Output() isSelectedEvent = new EventEmitter>();
+
+
+ constructor() {}
+
+ ngOnInit() {
+ this.isPropertyValueName = !this.propertyValueName ? false : true;
+ }
+
+ ngOnChanges() {
+ if (this.dataSource.length > 0) {
+ this.checkElementhasProperty();
+ this.selectedAllChecked(this.checkedAll);
+ }
+ }
+
+
+ /**
+ * Vérifie que tous les éléments de source de données possède la propriété "propertyValueName" lorsque cette dernière
+ * contient une valeur.
+ */
+ checkElementhasProperty() {
+ if(this.propertyValueName && !this.dataSource.every(e => e.hasOwnProperty(this.propertyValueName)))
+ throw new Error("Il existe au moins un élément dans la source de données qui ne possède pas la propriété '"+this.propertyValueName+"'.");
+ }
+
+
+ /**
+ * Détermine si l'élément est présent dans la liste des éléments sélectionnés
+ * @param element
+ */
+ exists(element) {
+ return this.elementsSelected.indexOf(element) > -1;
+ };
+
+ /**
+ * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedAllEvent"
+ * @param event case "Tout Sélectionner" cochée ou décochée
+ */
+ selectedAllChecked(event) {
+ this.isSelectedAllEvent.emit(event);
+ this.checkedAll = event;
+ this.elementsSelected = [];
+
+ if(event)
+ this.dataSource.map(data => this.elementsSelected.push(data));
+ }
+
+ /**
+ * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedEvent"
+ * @param event case cochée ou décochée par l'utilisateur
+ * @param data Valeur de la case cochée ou décochée
+ */
+ selectedChecked = (event: any, data: T) => {
+ this.isSelectedEvent.emit({isSelected: event, selectedElement: data});
+
+ // si la checkbox a été cochée
+ if(event)
+ this.elementsSelected.push(data);
+ else
+ this.elementsSelected = this.elementsSelected.filter(element => element != data);
+
+ // coche la case "Tout sélectionner" si tous les éléments sont cochés
+ this.elementsSelected.length == this.dataSource.length ? this.checkedAll = true: this.checkedAll = false;
+ }
+
+ /**
+ * Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires.
+ */
+ ngOnDestroy() {
+ }
+ }
+
\ No newline at end of file
diff --git a/src/app/shared/filter/filter.module.ts b/src/app/shared/filter/filter.module.ts
new file mode 100644
index 0000000..9d30ceb
--- /dev/null
+++ b/src/app/shared/filter/filter.module.ts
@@ -0,0 +1,28 @@
+import { NgModule } from "@angular/core";
+import { CommonModule } from '@angular/common';
+import { FormsModule, ReactiveFormsModule} from '@angular/forms';
+import { RouterModule } from '@angular/router';
+
+import { MaterialModule } from "../angular-material/angular-material.module";
+import { CheckboxFilterComponent } from "@shared/filter/checkbox-filter/checkbox-filter";
+import { SelectFilterComponent } from "@shared/filter/select-filter/select-filter";
+
+
+@NgModule({
+ declarations: [
+ CheckboxFilterComponent,
+ SelectFilterComponent
+ ],
+ imports: [
+ MaterialModule,
+ CommonModule,
+ FormsModule,
+ ReactiveFormsModule,
+ RouterModule
+ ],
+ exports: [
+ CheckboxFilterComponent,
+ SelectFilterComponent
+ ]
+})
+export class FilterModule {}
diff --git a/src/app/shared/filter/select-filter/select-filter.css b/src/app/shared/filter/select-filter/select-filter.css
new file mode 100644
index 0000000..8eea0ab
--- /dev/null
+++ b/src/app/shared/filter/select-filter/select-filter.css
@@ -0,0 +1,4 @@
+mat-select .mat-checkbox-layout,
+mat-select .mat-checkbox-label {
+ width:100% !important;
+}
\ No newline at end of file
diff --git a/src/app/shared/filter/select-filter/select-filter.html b/src/app/shared/filter/select-filter/select-filter.html
new file mode 100644
index 0000000..d3bb6c6
--- /dev/null
+++ b/src/app/shared/filter/select-filter/select-filter.html
@@ -0,0 +1,11 @@
+
+ {{label}}
+
+ Tout sélectionner
+
+ {{data[propertyValueName]}}
+ {{data}}
+
+
+
+
diff --git a/src/app/shared/filter/select-filter/select-filter.ts b/src/app/shared/filter/select-filter/select-filter.ts
new file mode 100644
index 0000000..6b1d985
--- /dev/null
+++ b/src/app/shared/filter/select-filter/select-filter.ts
@@ -0,0 +1,116 @@
+import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from "@angular/core";
+import { SelectedElement } from "@shared/filter/selected-element";
+
+@Component({
+ selector: "select-filter",
+ templateUrl: "./select-filter.html",
+ styleUrls: ["./select-filter.css"]
+})
+export class SelectFilterComponent implements OnInit, OnChanges {
+
+ /**
+ * Liste des éléments sélectionnés
+ */
+ elementsSelected: Array = [];
+
+ /**
+ * Booléen permettant de determiner si la propriété "propertyValueName" contient une valeur ou non
+ */
+ isPropertyValueName: boolean;
+
+ /**
+ * Libellé qui est affiché dans la liste déroulante lorsqu'aucune valeur n'est sélectionnée
+ */
+ @Input() label: string;
+
+ /**
+ * Cocher toutes les cases à cocher
+ */
+ @Input() checkedAll: boolean;
+
+ /**
+ * Source de données
+ */
+ @Input() dataSource : Array;
+
+ /**
+ * Nom de la propriété contenant la valeur à afficher
+ */
+ @Input() propertyValueName: string;
+
+ /**
+ * Booléen permettant de savoir si toutes les cases sont cochées ou non
+ */
+ @Output() isSelectedAllEvent = new EventEmitter();
+
+ /**
+ * Elément sélectionné
+ */
+ @Output() isSelectedEvent = new EventEmitter>();
+
+
+ constructor() {}
+
+ ngOnInit() {
+ this.isPropertyValueName = !this.propertyValueName ? false : true;
+ }
+
+ ngOnChanges() {
+ if (this.dataSource.length > 0) {
+ this.checkElementhasProperty();
+ this.selectedAllChecked(this.checkedAll);
+ }
+ }
+
+
+ /**
+ * Vérifie que tous les éléments de source de données possède la propriété "propertyValueName" lorsque cette dernière
+ * contient une valeur.
+ */
+ checkElementhasProperty() {
+ if(this.propertyValueName && !this.dataSource.every(e => e.hasOwnProperty(this.propertyValueName)))
+ throw new Error("Il existe au moins un élément dans la source de données qui ne possède pas la propriété '"+this.propertyValueName+"'.");
+ }
+
+ /**
+ * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedAllEvent"
+ * @param event case "Tout Sélectionner" cochée ou décochée
+ */
+ selectedAllChecked(event) {
+ this.isSelectedAllEvent.emit(event);
+ this.checkedAll = event;
+ this.elementsSelected = [];
+
+ if(event)
+ this.dataSource.map(data => this.elementsSelected.push(data));
+ }
+
+ /**
+ * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedEvent"
+ * @param isChecked case cochée ou décochée par l'utilisateur
+ * @param data Valeur de la case cochée ou décochée
+ */
+ selectedChecked = (isChecked: boolean, data: T) => {
+ this.isSelectedEvent.emit({isSelected: isChecked, selectedElement: data});
+
+ if(isChecked) {
+ var index = this.elementsSelected.findIndex(element => element == data);
+
+ if (index === -1)
+ this.elementsSelected.push(data);
+ }
+ else {
+ this.elementsSelected = this.elementsSelected.filter(element => element != data);
+ }
+
+ // coche la case "Tout sélectionner" si tous les éléments sont cochés
+ this.elementsSelected.length == this.dataSource.length ? this.checkedAll = true: this.checkedAll = false;
+ }
+
+ /**
+ * Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires.
+ */
+ ngOnDestroy() {
+ }
+ }
+
\ No newline at end of file
diff --git a/src/app/shared/filter/selected-element.ts b/src/app/shared/filter/selected-element.ts
new file mode 100644
index 0000000..fd68bbe
--- /dev/null
+++ b/src/app/shared/filter/selected-element.ts
@@ -0,0 +1,11 @@
+export interface SelectedElement {
+ /**
+ * Détermine si l'élément est sélectionné ou non
+ */
+ isSelected: boolean;
+
+ /**
+ * Element sélectionné
+ */
+ selectedElement: T;
+}
\ No newline at end of file