diff --git a/apps/maarch_entreprise/xml/services.xml b/apps/maarch_entreprise/xml/services.xml
index e7627eef87523a61187f55e20c7f61a7b6d2410d..b2de61e918840b0d9cff6efe7fb450ce023e3330 100755
--- a/apps/maarch_entreprise/xml/services.xml
+++ b/apps/maarch_entreprise/xml/services.xml
@@ -436,11 +436,11 @@
     <id>admin_indexing_models</id>
     <name>_ADMIN_INDEXING_MODELS</name>
     <comment>_ADMIN_INDEXING_MODELS</comment>
-    <servicepage>/administration/indexing-models</servicepage>
+    <servicepage>/administration/indexingModels</servicepage>
     <servicetype>admin</servicetype>
     <category>organisation</category>
     <system_service>false</system_service>
-    <style>fa fa-user</style>
+    <style>fab fa-wpforms</style>
     <enabled>true</enabled>
     <angular>true</angular>
   </SERVICE>
diff --git a/rest/index.php b/rest/index.php
index 18bcc9dc0bf893d86faccfd8f276a04f9864c347..0cd7ef9fac09a57d060c1bf7fa3a211c412b77e0 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -133,6 +133,13 @@ $app->post('/customFields', \CustomField\controllers\CustomFieldController::clas
 $app->put('/customFields/{id}', \CustomField\controllers\CustomFieldController::class . ':update');
 $app->delete('/customFields/{id}', \CustomField\controllers\CustomFieldController::class . ':delete');
 
+//IndexingModels
+$app->get('/indexingModels', \IndexingModel\controllers\IndexingModelController::class . ':get');
+$app->get('/indexingModels/{id}', \IndexingModel\controllers\IndexingModelController::class . ':getById');
+$app->post('/indexingModels', \IndexingModel\controllers\IndexingModelController::class . ':create');
+$app->put('/indexingModels/{id}', \IndexingModel\controllers\IndexingModelController::class . ':update');
+$app->delete('/indexingModels/{id}', \IndexingModel\controllers\IndexingModelController::class . ':delete');
+
 //Docservers
 $app->get('/docservers', \Docserver\controllers\DocserverController::class . ':get');
 $app->post('/docservers', \Docserver\controllers\DocserverController::class . ':create');
diff --git a/src/frontend/app/administration/administration-routing.module.ts b/src/frontend/app/administration/administration-routing.module.ts
index 72adae6a73e2145e6116c32fc5e632c8c8f71fb8..f7fe4eea4a5065a3870dcd9f02d6967a5a2dad8c 100755
--- a/src/frontend/app/administration/administration-routing.module.ts
+++ b/src/frontend/app/administration/administration-routing.module.ts
@@ -37,8 +37,9 @@ import { SecuritiesAdministrationComponent }            from './security/securit
 import { SendmailAdministrationComponent }              from './sendmail/sendmail-administration.component';
 import { ShippingsAdministrationComponent }             from './shipping/shippings-administration.component';
 import { ShippingAdministrationComponent }              from './shipping/shipping-administration.component';
-import { CustomFieldsAdministrationComponent }              from './customField/custom-fields-administration.component';
-import { AppGuard } from '../../service/app.guard';
+import { CustomFieldsAdministrationComponent }          from './customField/custom-fields-administration.component';
+import { AppGuard }                                     from '../../service/app.guard';
+import { IndexingModelsAdministrationComponent }        from './indexingModel/indexing-models-administration.component';
 
 @NgModule({
     imports: [
@@ -92,6 +93,9 @@ import { AppGuard } from '../../service/app.guard';
             { path: 'administration/shippings/new', canActivate: [AppGuard], component: ShippingAdministrationComponent },
             { path: 'administration/shippings/:id', canActivate: [AppGuard], component: ShippingAdministrationComponent },
             { path: 'administration/customFields', canActivate: [AppGuard], component: CustomFieldsAdministrationComponent },
+            /*{ path: 'administration/indexingModels', canActivate: [AppGuard], component: IndexingModelsAdministrationComponent },*/
+            { path: 'administration/indexingModels/new', canActivate: [AppGuard], component: IndexingModelsAdministrationComponent },
+            { path: 'administration/indexingModels/:id', canActivate: [AppGuard], component: IndexingModelsAdministrationComponent },
         ]),
     ],
     exports: [
diff --git a/src/frontend/app/administration/administration.module.ts b/src/frontend/app/administration/administration.module.ts
index 7a62b18c9125b8b3c7934b0c609bc1854a6bd2f0..8a82938fdfb23353d1da20aee0ad8ac5f863d5b9 100755
--- a/src/frontend/app/administration/administration.module.ts
+++ b/src/frontend/app/administration/administration.module.ts
@@ -50,6 +50,7 @@ import { ListAdministrationComponent }                  from './basket/list/list
 import { ShippingsAdministrationComponent }              from './shipping/shippings-administration.component';
 import { ShippingAdministrationComponent }              from './shipping/shipping-administration.component';
 import { CustomFieldsAdministrationComponent }              from './customField/custom-fields-administration.component';
+import { IndexingModelsAdministrationComponent }              from './indexingModel/indexing-models-administration.component';
 
 @NgModule({
     imports:      [
@@ -109,7 +110,8 @@ import { CustomFieldsAdministrationComponent }              from './customField/
         ShippingsAdministrationComponent,
         ShippingAdministrationComponent,
         AccountLinkComponent,
-        CustomFieldsAdministrationComponent
+        CustomFieldsAdministrationComponent,
+        IndexingModelsAdministrationComponent
     ],
     entryComponents: [
         UsersAdministrationRedirectModalComponent,
diff --git a/src/frontend/app/administration/indexingModel/indexing-models-administration.component.html b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..df16f04f342b1870cd209d94aaeec7a881187cdb
--- /dev/null
+++ b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.html
@@ -0,0 +1,50 @@
+<div class="admin-container" [class.admin-is-mobile]="appService.getViewMode()">
+    <mat-sidenav-container autosize class="admin-sidenav-container">
+        <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'"
+            [fixedInViewport]="appService.getViewMode()" fixedTopGap="56"
+            [opened]="appService.getViewMode() ? false : true">
+            <menu-shortcut></menu-shortcut>
+            <menu-nav></menu-nav>
+        </mat-sidenav>
+        <mat-sidenav-content>
+            <div *ngIf="loading" style="display:flex;height:100%;">
+                <mat-spinner style="margin:auto;"></mat-spinner>
+            </div>
+            <mat-card *ngIf="!loading" class="card-app-content">
+                <div style="display: flex;">
+                    <div style="flex:1;">
+                        <mat-form-field class="indexingModelLabel" appearance="outline">
+                            <mat-label>{{lang.modelName}}</mat-label>
+                            <input matInput name="label" [(ngModel)]="indexingModel.label">
+                        </mat-form-field>
+                    </div>
+                    <div class="defaultModel">
+                        <mat-slide-toggle color="primary" name="default" [(ngModel)]="indexingModel.default">{{lang.defaultModel}}
+                        </mat-slide-toggle>
+                    </div>
+                </div>
+                <mat-tab-group>
+                    <mat-tab [label]="lang.indexingForm">
+                        <app-indexing-form #indexingForm></app-indexing-form>
+                        <div class="col-md-12 text-center">
+                            <button mat-raised-button color="primary" (click)="onSubmit()"
+                                [disabled]="!indexingForm.isModified() && !isModified()">{{lang.update}}</button>
+                        </div>
+                    </mat-tab>
+                </mat-tab-group>
+            </mat-card>
+        </mat-sidenav-content>
+        <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'"
+            [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" position='end' opened
+            class="col-md-4 col-sm-12">
+            <mat-tab-group>
+                <mat-tab [label]="lang.availableCustomFields">
+                    <app-field-list *ngIf="indexingForm !== undefined" [dataCustomFields]="indexingForm.getAvailableCustomFields()"></app-field-list>
+                </mat-tab>
+                <mat-tab [label]="lang.availableFields">
+                    <app-field-list *ngIf="indexingForm !== undefined" [dataFields]="indexingForm.getAvailableFields()"></app-field-list>
+                </mat-tab>
+            </mat-tab-group>
+        </mat-sidenav>
+    </mat-sidenav-container>
+</div>
\ No newline at end of file
diff --git a/src/frontend/app/administration/indexingModel/indexing-models-administration.component.scss b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f1485c1bb404488a5525a4b10a04fcb400e34616
--- /dev/null
+++ b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.scss
@@ -0,0 +1,14 @@
+@import '../../../css/vars.scss';
+
+.indexingModelLabel {
+    ::ng-deep.mat-form-field-wrapper {
+        padding: 0px;
+    }
+}
+
+.defaultModel {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding-left: 10px;
+}
\ No newline at end of file
diff --git a/src/frontend/app/administration/indexingModel/indexing-models-administration.component.ts b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d239c038e22c4bd03e128159250c61799f2959db
--- /dev/null
+++ b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.ts
@@ -0,0 +1,165 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { LANG } from '../../translate.component';
+import { NotificationService } from '../../notification.service';
+import { HeaderService } from '../../../service/header.service';
+import { MatDialog } from '@angular/material/dialog';
+import { MatSidenav } from '@angular/material/sidenav';
+import { AppService } from '../../../service/app.service';
+import { tap, catchError, finalize } from 'rxjs/operators';
+import { of } from 'rxjs';
+import { SortPipe } from '../../../plugins/sorting.pipe';
+import { IndexingFormComponent } from '../../indexation/indexing-form/indexing-form.component';
+import { ActivatedRoute } from '@angular/router';
+
+declare function $j(selector: any): any;
+
+@Component({
+    templateUrl: "indexing-models-administration.component.html",
+    styleUrls: [
+        'indexing-models-administration.component.scss',
+        '../../indexation/indexing-form/indexing-form.component.scss'
+    ],
+    providers: [NotificationService, AppService, SortPipe]
+})
+
+export class IndexingModelsAdministrationComponent implements OnInit {
+
+    @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav;
+    @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav;
+
+    @ViewChild('indexingForm', { static: false }) indexingForm: IndexingFormComponent;
+
+    lang: any = LANG;
+
+    loading: boolean = false;
+
+    indexingModel: any = {
+        id: 0,
+        label: '',
+        default: false,
+        owner: 0,
+        private: false
+    };
+
+    indexingModelClone: any;
+
+    indexingModelsCustomFields: any[] = [];
+
+    creationMode: boolean = true;
+
+    availableFields: any[] = [
+        {
+            identifier: 'priority',
+            label: this.lang.priority,
+            type: 'select',
+            values: []
+        },
+        {
+            identifier: 'confidential',
+            label: this.lang.confidential,
+            type: 'radio',
+            values: ['yes', 'no']
+        },
+        {
+            identifier: 'initiator',
+            label: this.lang.initiator,
+            type: 'select',
+            values: []
+        },
+        {
+            identifier: 'processLimitDate',
+            label: this.lang.processLimitDate,
+            type: 'date',
+            values: []
+        },
+        {
+            identifier: 'arrivalDate',
+            label: this.lang.arrivalDate,
+            type: 'date',
+            values: []
+        }
+    ];
+
+    availableCustomFields: any[] = []
+
+    constructor(
+        public http: HttpClient,
+        private route: ActivatedRoute,
+        private notify: NotificationService,
+        public dialog: MatDialog,
+        private headerService: HeaderService,
+        public appService: AppService,
+    ) {
+
+    }
+
+    ngOnInit(): void {
+        window['MainHeaderComponent'].setSnav(this.sidenavLeft);
+        window['MainHeaderComponent'].setSnavRight(this.sidenavRight);
+
+        this.route.params.subscribe((params) => {
+            if (typeof params['id'] == "undefined") {
+                this.headerService.setHeader(this.lang.administration);
+                this.creationMode = true;
+                this.loading = false;
+
+            } else {
+                this.creationMode = false;
+
+                this.http.get("../../rest/indexingModels/" + params['id']).pipe(
+                    tap((data: any) => {
+                        this.indexingModel = data.indexingModel;
+                        
+                        this.headerService.setHeader(this.lang.indexingModelModification, this.indexingModel.label);
+
+                        this.indexingModelClone = JSON.parse(JSON.stringify(this.indexingModel));
+
+                    }),
+                    finalize(() => this.loading = false),
+                    catchError((err: any) => {
+                        this.notify.handleErrors(err);
+                        return of(false);
+                    })
+                ).subscribe();
+            }
+        });
+
+
+    }
+
+    onSubmit() {
+        this.indexingModel.fields = this.indexingForm.getDatas();
+
+        this.http.put("../../rest/indexingModels/" + this.indexingModel.id, this.indexingModel).pipe(
+            tap((data: any) => {
+                this.indexingForm.setModification();
+                this.setModification();
+                this.notify.success('sucess!');
+            }),
+            finalize(() => this.loading = false),
+            catchError((err: any) => {
+                this.notify.handleErrors(err);
+                return of(false);
+            })
+        ).subscribe();
+    }
+
+    isModified() {
+        let compare: string = '';
+        let compareClone: string = '';
+
+        compare = JSON.stringify(this.indexingModel);
+        compareClone = JSON.stringify(this.indexingModelClone);
+
+        if(compare !== compareClone) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    setModification() {
+        this.indexingModelClone = JSON.parse(JSON.stringify(this.indexingModel));
+    }
+}
\ No newline at end of file
diff --git a/src/frontend/app/app-common.module.ts b/src/frontend/app/app-common.module.ts
index c75bf65044f546ab03025646d155410879613dc0..2448f33a2447ddfab925adcd877d7e0f4105c564 100755
--- a/src/frontend/app/app-common.module.ts
+++ b/src/frontend/app/app-common.module.ts
@@ -43,6 +43,10 @@ import { SearchHomeComponent }                        from './search/search-home
 import { BasketHomeComponent }                        from './basket/basket-home.component';
 
 
+import { IndexingFormComponent }                        from './indexation/indexing-form/indexing-form.component';
+import { FieldListComponent }                        from './indexation/field-list/field-list.component';
+
+
 /*MODAL*/
 import { AlertComponent }                        from '../plugins/modal/alert.component';
 import { ConfirmComponent }                        from '../plugins/modal/confirm.component';
@@ -92,7 +96,9 @@ export class MyHammerConfig extends HammerGestureConfig {
         SmdFabSpeedDialActions,
         AlertComponent,
         ConfirmComponent,
-        PluginAutocomplete
+        PluginAutocomplete,
+        IndexingFormComponent,
+        FieldListComponent
     ],
     exports: [
         CommonModule,
@@ -122,7 +128,9 @@ export class MyHammerConfig extends HammerGestureConfig {
         SmdFabSpeedDialTrigger,
         SmdFabSpeedDialActions,
         DragDropModule,
-        PluginAutocomplete
+        PluginAutocomplete,
+        IndexingFormComponent,
+        FieldListComponent
     ],
     providers: [
         LatinisePipe,
diff --git a/src/frontend/app/indexation/field-list/field-list.component.html b/src/frontend/app/indexation/field-list/field-list.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..ffe118b1c3a2eee3e86d18c1b0a8b2e591fb3192
--- /dev/null
+++ b/src/frontend/app/indexation/field-list/field-list.component.html
@@ -0,0 +1,131 @@
+<div *ngIf="availableCustomFields !== undefined" class="content" cdkDropList id="customFieldsList"
+    [cdkDropListConnectedTo]="['indexingModelsCustomFieldsList_mail','indexingModelsCustomFieldsList_contact','indexingModelsCustomFieldsList_process','indexingModelsCustomFieldsList_classement']"
+    [cdkDropListData]="availableCustomFields" (cdkDropListDropped)="drop($event)">
+    <div class="customFieldRow" *ngFor="let field of availableCustomFields" cdkDrag
+        [cdkDragData]="field">
+        <div class="customFieldDrag">
+            <i color="primary" class="fas fa-arrows-alt fa-2x" cdkDragHandle></i>
+        </div>
+        <div style="flex:1;display: flex;">
+            <div class="fieldLabel">
+                {{field.label}}
+            </div>
+            <div class="fieldInput" [class.advancedInput]="field.type === 'checkbox'">
+                <ng-container *ngIf="field.type === 'string'">
+                    <mat-form-field class="input-form" floatLabel="never">
+                        <textarea matInput [placeholder]="lang[field.type + 'Input']" matTextareaAutosize
+                            matAutosizeMinRows="1" cdkAutosizeMaxRows="6"></textarea>
+                    </mat-form-field>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'select'">
+                    <mat-form-field class="input-form" floatLabel="never">
+                        <mat-select [placeholder]="lang[field.type + 'Input']">
+                            <mat-option *ngFor="let value of field.values" [value]="value">
+                                {{value}}
+                            </mat-option>
+                        </mat-select>
+                    </mat-form-field>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'date'">
+                    <mat-form-field class="input-form" floatLabel="never">
+                        <input matInput [matDatepicker]="picker" [placeholder]="lang[field.type + 'Input']"
+                            (click)="picker.open()">
+                        <mat-datepicker-toggle matSuffix [for]="picker">
+                        </mat-datepicker-toggle>
+                        <mat-datepicker #picker></mat-datepicker>
+                    </mat-form-field>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'radio'">
+                    <mat-radio-group class="radio-form" color="primary">
+                        <mat-radio-button *ngFor="let value of field.values" [value]="value">
+                            {{value}}
+                        </mat-radio-button>
+                    </mat-radio-group>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'checkbox'">
+                    <div class="input-form checkbox-form">
+                        <mat-selection-list #shoes class="div-list">
+                            <mat-list-option *ngFor="let value of field.values" [value]="value"
+                                checkboxPosition="before">
+                                {{value}}
+                            </mat-list-option>
+                        </mat-selection-list>
+                    </div>
+                    <mat-chip-list class="checkbox-selected-list">
+                        <mat-chip *ngFor="let chip of shoes.selectedOptions.selected" selected>
+                            {{lang.selectedValue}}
+                        </mat-chip>
+                    </mat-chip-list>
+                </ng-container>
+            </div>
+            <div class="fieldState">
+                <i class="fas fa-asterisk" [class.noMandatory]="!field.mandatory"></i>
+            </div>
+        </div>
+    </div>
+</div>
+<div *ngIf="availableFields !== undefined" class="content" cdkDropList id="fieldsList"
+    [cdkDropListConnectedTo]="['indexingModelsCustomFieldsList_mail','indexingModelsCustomFieldsList_contact','indexingModelsCustomFieldsList_process','indexingModelsCustomFieldsList_classement']"
+    [cdkDropListData]="availableFields" (cdkDropListDropped)="drop($event)">
+    <div class="customFieldRow" *ngFor="let field of availableFields" cdkDrag [cdkDragData]="field">
+        <div class="customFieldDrag" cdkDragHandle>
+            <i color="primary" class="fas fa-arrows-alt fa-2x"></i>
+        </div>
+        <div style="flex:1;display: flex;">
+            <div class="fieldLabel">
+                {{field.label}}
+            </div>
+            <div class="fieldInput">
+                <ng-container *ngIf="field.type === 'string'">
+                    <mat-form-field class="input-form" floatLabel="never">
+                        <textarea matInput [placeholder]="lang[field.type + 'Input']" matTextareaAutosize
+                            matAutosizeMinRows="1" cdkAutosizeMaxRows="6"></textarea>
+                    </mat-form-field>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'select'">
+                    <mat-form-field class="input-form" floatLabel="never">
+                        <mat-select [placeholder]="lang[field.type + 'Input']">
+                            <mat-option *ngFor="let value of field.values" [value]="value">
+                                {{value}}
+                            </mat-option>
+                        </mat-select>
+                    </mat-form-field>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'date'">
+                    <mat-form-field class="input-form" floatLabel="never">
+                        <input matInput [matDatepicker]="picker" [placeholder]="lang[field.type + 'Input']"
+                            (click)="picker.open()">
+                        <mat-datepicker-toggle matSuffix [for]="picker">
+                        </mat-datepicker-toggle>
+                        <mat-datepicker #picker></mat-datepicker>
+                    </mat-form-field>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'radio'">
+                    <mat-radio-group class="radio-form" color="primary">
+                        <mat-radio-button *ngFor="let value of field.values" [value]="value">
+                            {{value}}
+                        </mat-radio-button>
+                    </mat-radio-group>
+                </ng-container>
+                <ng-container *ngIf="field.type === 'checkbox'">
+                    <div class="input-form checkbox-form">
+                        <mat-selection-list #shoes class="div-list">
+                            <mat-list-option *ngFor="let value of field.values" [value]="value"
+                                checkboxPosition="before">
+                                {{value}}
+                            </mat-list-option>
+                        </mat-selection-list>
+                    </div>
+                    <mat-chip-list class="checkbox-selected-list">
+                        <mat-chip *ngFor="let chip of shoes.selectedOptions.selected" selected>
+                            {{lang.selectedValue}}
+                        </mat-chip>
+                    </mat-chip-list>
+                </ng-container>
+            </div>
+            <div class="fieldState">
+                <i class="fas fa-asterisk" [class.noMandatory]="!field.mandatory"></i>
+            </div>
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/frontend/app/indexation/field-list/field-list.component.scss b/src/frontend/app/indexation/field-list/field-list.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a51c80f154a1252f042f167d98280c25b770ba7d
--- /dev/null
+++ b/src/frontend/app/indexation/field-list/field-list.component.scss
@@ -0,0 +1 @@
+@import '../../../css/vars.scss';
diff --git a/src/frontend/app/indexation/field-list/field-list.component.ts b/src/frontend/app/indexation/field-list/field-list.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..35cba548c2dc566e238b038d5c31ee300e14472c
--- /dev/null
+++ b/src/frontend/app/indexation/field-list/field-list.component.ts
@@ -0,0 +1,57 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { LANG } from '../../translate.component';
+import { NotificationService } from '../../notification.service';
+import { HeaderService } from '../../../service/header.service';
+import { MatDialog } from '@angular/material/dialog';
+import { AppService } from '../../../service/app.service';
+import { SortPipe } from '../../../plugins/sorting.pipe';
+import { moveItemInArray, CdkDragDrop, transferArrayItem } from '@angular/cdk/drag-drop';
+
+declare function $j(selector: any): any;
+
+@Component({
+    selector: 'app-field-list',
+    templateUrl: "field-list.component.html",
+    styleUrls: [
+        'field-list.component.scss', 
+        '../../indexation/indexing-form/indexing-form.component.scss'
+    ],
+    providers: [NotificationService, AppService, SortPipe]
+})
+
+export class FieldListComponent implements OnInit {
+
+    lang: any = LANG;
+
+    loading: boolean = false;
+
+    @Input('dataFields') availableCustomFields: any[];
+
+    @Input('dataCustomFields') availableFields: any[];
+
+    constructor(
+        public http: HttpClient,
+        private notify: NotificationService,
+        public dialog: MatDialog,
+        private headerService: HeaderService,
+        public appService: AppService,
+        private sortPipe: SortPipe
+    ) { }
+
+    ngOnInit(): void { }
+
+    drop(event: CdkDragDrop<string[]>) {
+        event.item.data.unit = event.container.id.split('_')[1];
+
+        if (event.previousContainer === event.container) {
+            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
+        } else {
+
+            transferArrayItem(event.previousContainer.data,
+                event.container.data,
+                event.previousIndex,
+                event.currentIndex);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/frontend/app/indexation/indexing-form/indexing-form.component.html b/src/frontend/app/indexation/indexing-form/indexing-form.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..5900f54314d4db742c2837c3e80b5d3344231e16
--- /dev/null
+++ b/src/frontend/app/indexation/indexing-form/indexing-form.component.html
@@ -0,0 +1,92 @@
+<div class="banner" *ngFor="let category of fieldCategories">
+    <div class="title">
+        {{lang[category] | uppercase}}
+        <div class="title-divider"></div>
+    </div>
+    <div class="content">
+        <div cdkDropList id="indexingModelsCustomFieldsList_{{category}}"
+            [cdkDropListConnectedTo]="['indexingModelsCustomFieldsList_mail','indexingModelsCustomFieldsList_contact','indexingModelsCustomFieldsList_process','indexingModelsCustomFieldsList_classement','customFieldsList','fieldsList']"
+            [cdkDropListData]="this['indexingModels_'+category]" (cdkDropListDropped)="drop($event)"
+            class="indexingModelsCustomFieldsList" style="min-height: 50px;">
+            <ng-container *ngFor="let field of this['indexingModels_'+category];let i=index">
+                <div class="fieldRow" *ngIf="field.unit === category" cdkDrag cdkDragLockAxis="y" [cdkDragData]="field">
+                    <div class="fieldLabel">
+                        <i class="fas fa-bars fa-2x" color="primary" style="cursor: move" cdkDragHandle></i>&nbsp;
+                        <button mat-icon-button [matMenuTriggerFor]="fieldActions" *ngIf="!field.system">
+                            <mat-icon class="fa fa-ellipsis-v" color="secondary"></mat-icon>
+                        </button>
+                        <mat-menu #fieldActions="matMenu">
+                            <button mat-menu-item (click)="field.mandatory = !field.mandatory">
+                                <span *ngIf="!field.mandatory">{{lang.mandatoryField}}</span>
+                                <span *ngIf="field.mandatory">{{lang.optionalField}}</span>
+                            </button>
+                            <mat-divider></mat-divider>
+                            <button mat-menu-item (click)="removeItem('indexingModels_'+category,field,i)">
+                                <mat-icon class="fa fa-trash" color="warn"></mat-icon>
+                                <span>{{lang.delete}}</span>
+                            </button>
+                        </mat-menu>{{field.label}}
+                    </div>
+                    <div class="fieldInput">
+                        <ng-container *ngIf="field.type === 'string'">
+                            <mat-form-field class="input-form" floatLabel="never">
+                                <textarea matInput [(ngModel)]="field.default_value"
+                                    [placeholder]="field.system ? lang[field.type + 'Input'] : lang.defaultValue"
+                                    matTextareaAutosize matAutosizeMinRows="1" cdkAutosizeMaxRows="6"
+                                    [disabled]="field.system"></textarea>
+                            </mat-form-field>
+                        </ng-container>
+                        <ng-container *ngIf="field.type === 'select'">
+                            <mat-form-field class="input-form" floatLabel="never">
+                                <mat-select
+                                    [placeholder]="field.system ? lang[field.type + 'Input'] : lang.defaultValue"
+                                    [(ngModel)]="field.default_value" [disabled]="field.system">
+                                    <mat-option *ngFor="let value of field.values" [value]="value">
+                                        {{value}}
+                                    </mat-option>
+                                </mat-select>
+                            </mat-form-field>
+                        </ng-container>
+                        <ng-container *ngIf="field.type === 'date'">
+                            <mat-form-field class="input-form" floatLabel="never" (click)="picker.open()">
+                                <input matInput [matDatepicker]="picker"
+                                    [placeholder]="field.system ? lang[field.type + 'Input'] : lang.defaultValue"
+                                    [(ngModel)]="field.default_value" [disabled]="field.system">
+                                <mat-datepicker-toggle matSuffix [for]="picker">
+                                </mat-datepicker-toggle>
+                                <mat-datepicker #picker></mat-datepicker>
+                            </mat-form-field>
+                        </ng-container>
+                        <ng-container *ngIf="field.type === 'radio'">
+                            <mat-radio-group class="radio-form" color="primary" [disabled]="field.system"
+                                [(ngModel)]="field.default_value">
+                                <mat-radio-button *ngFor="let value of field.values" [value]="value">
+                                    {{value}}
+                                </mat-radio-button>
+                            </mat-radio-group>
+                        </ng-container>
+                        <ng-container *ngIf="field.type === 'checkbox'">
+                            <div class="input-form checkbox-form">
+                                <mat-selection-list #shoes class="div-list" [disabled]="field.system"
+                                    [(ngModel)]="field.default_value">
+                                    <mat-list-option *ngFor="let value of field.values" [value]="value"
+                                        checkboxPosition="before">
+                                        {{value}}
+                                    </mat-list-option>
+                                </mat-selection-list>
+                            </div>
+                            <mat-chip-list class="checkbox-selected-list" [disabled]="field.system">
+                                <mat-chip *ngFor="let chip of shoes.selectedOptions.selected" selected>
+                                    {{lang.selectedValue}}
+                                </mat-chip>
+                            </mat-chip-list>
+                        </ng-container>
+                    </div>
+                    <div class="fieldState">
+                        <i class="fas fa-asterisk" [class.noMandatory]="!field.mandatory"></i>
+                    </div>
+                </div>
+            </ng-container>
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/frontend/app/indexation/indexing-form/indexing-form.component.scss b/src/frontend/app/indexation/indexing-form/indexing-form.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..79f4fbf7b6b7c908c004fbf7bf2e834529d1d5d7
--- /dev/null
+++ b/src/frontend/app/indexation/indexing-form/indexing-form.component.scss
@@ -0,0 +1,241 @@
+@import '../../../css/vars.scss';
+
+.banner {
+    display: flex;
+    flex-direction: column;
+    margin-top: 30px;
+    border-radius: 20px;
+    border: solid 1px #ccc;
+    position: relative;
+    padding: 20px;
+    width: 100%;
+
+    .title {
+        white-space: pre;
+        overflow: hidden;
+        max-width: 85%;
+        text-overflow: ellipsis;
+        z-index: 1;
+        font-size: 20px;
+        font-weight: bold;
+        letter-spacing: 2px;
+        position: absolute;
+        top: -18px;
+        left: 20px;
+        padding: 0px;
+        margin: 0px;
+        color: $primary;
+
+        &-divider {
+            position: absolute;
+            width: 99%;
+            z-index: -1;
+            top: 17px;
+            background: white;
+            height: 1px;
+        }
+    }
+
+    .content {
+        font-size: 16px;
+    }
+}
+
+.fieldRow {
+    display: flex;
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+
+.fieldLabel {
+    color: #4A4A4A;
+}
+
+.fieldState {
+    padding-left: 10px;
+    padding-right: 10px;
+
+    i {
+        font-size: 5px;
+        color: $primary;
+    }
+}
+
+.fieldLabel,
+.fieldInput {
+    font-size: 13px;
+    flex: 1;
+}
+
+.fieldLabel,
+.fieldInput,
+.fieldState {
+    align-items: center;
+    display: flex;
+
+}
+
+.input-form {
+    color: #666;
+    width: 500px;
+
+    .mat-input-element {
+        color: $primary;
+        padding-left: 20px;
+    }
+
+    input {
+        padding-left: 20px;
+        padding-right: 20px;
+    }
+
+    ::ng-deep.mat-select-value-text {
+        padding-left: 20px;
+        color: $primary;
+    }
+
+    ::ng-deep.mat-form-field-label {
+        left: 20px;
+    }
+
+    ::ng-deep.mat-form-field-infix {
+        padding-bottom: 15px;
+    }
+
+    ::ng-deep.mat-form-field-flex {
+        background: white;
+        border-radius: 30px;
+        border: solid 1px $primary;
+    }
+
+    ::ng-deep .mat-form-field-underline {
+        display: none;
+    }
+
+    ::ng-deep.mat-form-field-suffix {
+        margin-right: 20px;
+    }
+
+    ::ng-deep.mat-select-arrow-wrapper {
+        padding-right: 20px;
+    }
+
+    ::ng-deep.mat-list-option {
+        color: rgba(0, 0, 0, 0.54);
+    }
+
+    ::ng-deep.mat-form-field-wrapper {
+        padding: 0px;
+    }
+
+    textarea.cdk-textarea-autosize-measuring {
+        padding: 4px 0 !important;
+    }
+
+    ::ng-deep.mat-datepicker-toggle-default-icon {
+        height: auto;
+    }
+}
+
+.mat-form-field-disabled {
+    ::ng-deep.mat-input-element {
+        cursor: not-allowed;
+        padding-left: 20px;
+    }
+
+    ::ng-deep.mat-form-field-flex {
+        cursor: not-allowed;
+        border: dashed 1px rgb(53, 50, 50);
+    }
+}
+
+.div-list {
+
+    padding: 0px;
+    max-height: 150px;
+    overflow: auto;
+
+    .mat-list-item {
+        font-size: 13px;
+    }
+}
+
+.checkbox-form {
+    width: 100%;
+    padding: 0px;
+    border: solid 1px $primary;
+    border-radius: 30px;
+    overflow: hidden;
+}
+
+.checkbox-selected-list {
+    margin-top: 10px;
+    display: flex;
+    justify-content: center;
+
+    ::ng-deep.mat-chip-list-wrapper {
+        justify-content: center;
+    }
+
+    .mat-chip {
+        font-size: 13px;
+    }
+}
+
+.radio-form {
+    display: flex;
+    width: 100%;
+
+    .mat-radio-button {
+        flex: 1;
+
+        ::ng-deep.mat-radio-label-content {
+            font-weight: normal;
+            color: rgba(0, 0, 0, 0.54);
+        }
+    }
+
+}
+
+.disabled {
+    opacity: 0.2;
+}
+
+.customFieldRow {
+    display: flex;
+    padding-top: 20px;
+    padding-bottom: 20px;
+}
+
+.customFieldDrag {
+    cursor: grab;
+    width: 50px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.cdk-drag-animating {
+    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
+}
+
+.cdk-drag-preview {
+    background: white;
+    box-sizing: border-box;
+    border-radius: 4px;
+    box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
+        0 8px 10px 1px rgba(0, 0, 0, 0.14),
+        0 3px 14px 2px rgba(0, 0, 0, 0.12);
+}
+
+.indexingModelsCustomFieldsList.cdk-drop-list-dragging .indexingModelsCustomFieldsList:not(.cdk-drag-placeholder) {
+    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
+}
+
+.advancedInput {
+    flex-direction: column;
+}
+
+.noMandatory {
+    visibility: hidden;
+}
\ No newline at end of file
diff --git a/src/frontend/app/indexation/indexing-form/indexing-form.component.ts b/src/frontend/app/indexation/indexing-form/indexing-form.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..421a8f07bb6fed6a48cbd6c8d544e114ae0fe67e
--- /dev/null
+++ b/src/frontend/app/indexation/indexing-form/indexing-form.component.ts
@@ -0,0 +1,309 @@
+import { Component, OnInit } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { LANG } from '../../translate.component';
+import { NotificationService } from '../../notification.service';
+import { HeaderService } from '../../../service/header.service';
+import { MatDialog } from '@angular/material/dialog';
+import { AppService } from '../../../service/app.service';
+import { tap, catchError, finalize, exhaustMap } from 'rxjs/operators';
+import { of } from 'rxjs';
+import { SortPipe } from '../../../plugins/sorting.pipe';
+import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
+
+@Component({
+    selector: 'app-indexing-form',
+    templateUrl: "indexing-form.component.html",
+    styleUrls: ['indexing-form.component.scss'],
+    providers: [NotificationService, AppService, SortPipe]
+})
+
+export class IndexingFormComponent implements OnInit {
+
+    lang: any = LANG;
+
+    loading: boolean = false;
+
+    fieldCategories: any[] = ['mail', 'contact', 'process', 'classement'];
+
+    indexingModelsCore: any[] = [
+        {
+            identifier: 'category_id',
+            label: 'Catégorie',
+            unit: 'mail',
+            type: 'select',
+            system: true,
+            mandatory: true,
+            values: []
+        },
+        {
+            identifier: 'doctype',
+            label: 'Type de courrier',
+            unit: 'mail',
+            type: 'select',
+            system: true,
+            mandatory: true,
+            values: []
+        },
+        {
+            identifier: 'docDate',
+            label: 'Date du courrier',
+            unit: 'mail',
+            type: 'date',
+            system: true,
+            mandatory: true,
+            values: []
+        },
+        {
+            identifier: 'arrivalDate',
+            label: 'Date d\'arrivée',
+            unit: 'mail',
+            type: 'date',
+            system: true,
+            mandatory: true,
+            values: []
+        },
+        {
+            identifier: 'subject',
+            label: 'Objet',
+            unit: 'mail',
+            type: 'string',
+            system: true,
+            mandatory: true,
+            values: []
+        },
+        {
+            identifier: 'contact',
+            label: 'Expéditeur',
+            unit: 'contact',
+            type: 'string',
+            system: true,
+            mandatory: true,
+            values: []
+        },
+        {
+            identifier: 'destination',
+            label: 'Service traitant',
+            unit: 'process',
+            type: 'select',
+            system: true,
+            mandatory: true,
+            values: []
+        },
+        {
+            identifier: 'folder',
+            label: 'Dossier',
+            unit: 'classement',
+            type: 'string',
+            system: true,
+            mandatory: true,
+            values: []
+        }
+    ];
+
+    indexingModels_mail: any[] = [];
+    indexingModels_contact: any[] = [];
+    indexingModels_process: any[] = [];
+    indexingModels_classement: any[] = [];
+
+    indexingModels_mailClone: any[] = [];
+    indexingModels_contactClone: any[] = [];
+    indexingModels_processClone: any[] = [];
+    indexingModels_classementClone: any[] = [];
+
+    indexingModelsCustomFields: any[] = [];
+
+    availableFields: any[] = [
+        {
+            identifier: 'priority',
+            label: this.lang.priority,
+            type: 'select',
+            values: []
+        },
+        {
+            identifier: 'confidential',
+            label: this.lang.confidential,
+            type: 'radio',
+            values: ['yes', 'no']
+        },
+        {
+            identifier: 'initiator',
+            label: this.lang.initiator,
+            type: 'select',
+            values: []
+        },
+        {
+            identifier: 'processLimitDate',
+            label: this.lang.processLimitDate,
+            type: 'date',
+            values: []
+        },
+        {
+            identifier: 'arrivalDate',
+            label: this.lang.arrivalDate,
+            type: 'date',
+            values: []
+        }
+    ];
+
+    availableCustomFields: any[] = []
+
+    constructor(
+        public http: HttpClient,
+        private notify: NotificationService,
+        public dialog: MatDialog,
+        private headerService: HeaderService,
+        public appService: AppService,
+    ) {
+
+    }
+
+    ngOnInit(): void {
+
+        this.fieldCategories.forEach(category => {
+            this['indexingModels_' + category] = [];
+        });
+
+        this.http.get("../../rest/customFields").pipe(
+            tap((data: any) => {
+                this.availableCustomFields = data.customFields.map((info: any) => {
+                    info.identifier = 'indexingCustomField_' + info.id;
+                    info.system = false;
+                    return info;
+                });
+            }),
+            exhaustMap((data) => this.http.get("../../rest/indexingModels/1")),
+            tap((data: any) => {
+                let fieldExist: boolean;
+                if (data.indexingModel.fields.length === 0) {
+                    this.fieldCategories.forEach(element => {
+                        this['indexingModels_' + element] = this.indexingModelsCore.filter((x: any, i: any, a: any) => x.unit === element);
+                    });
+                    this.notify.error("Champs introuvables! les données de base ont été chargés");
+                } else {
+                    data.indexingModel.fields.forEach((field: any) => {
+                        fieldExist = false;
+                        field.label = this.lang[field.identifier];
+                        field.system = false;
+                        field.values = [];
+    
+                        let indexFound = this.availableFields.map(avField => avField.identifier).indexOf(field.identifier);
+    
+                        if (indexFound > -1) {
+                            field.label = this.availableFields[indexFound].label;
+                            field.values = this.availableFields[indexFound].values;
+                            field.type = this.availableFields[indexFound].type;
+                            this.availableFields.splice(indexFound, 1);
+                            fieldExist = true;
+                        }
+    
+                        indexFound = this.availableCustomFields.map(avField => avField.identifier).indexOf(field.identifier);
+                        
+                        if (indexFound > -1) {
+                            field.label = this.availableCustomFields[indexFound].label;
+                            field.values = this.availableCustomFields[indexFound].values;
+                            field.type = this.availableCustomFields[indexFound].type;
+                            this.availableCustomFields.splice(indexFound, 1);
+                            fieldExist = true;
+                        }
+                        if (this.indexingModelsCore.map(info => info.identifier).indexOf(field.identifier) > -1) {
+                            fieldExist = true;
+                            field.system = true;
+                        }
+    
+                        if (fieldExist) {
+                            this['indexingModels_' + field.unit].push(field);
+                        } else {
+                            this.notify.error("Le champ "+ field.identifier+" n'existe pas !");
+                        }
+                        
+                    });
+                }
+                this.fieldCategories.forEach(element => {
+                    this['indexingModels_' + element + 'Clone'] = JSON.parse(JSON.stringify(this['indexingModels_' + element]));
+                });
+            }),
+            finalize(() => this.loading = false),
+            catchError((err: any) => {
+                this.notify.handleErrors(err);
+                return of(false);
+            })
+        ).subscribe();
+    }
+
+    drop(event: CdkDragDrop<string[]>) {
+        event.item.data.unit = event.container.id.split('_')[1];
+
+        if (event.previousContainer === event.container) {
+            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
+        } else {
+
+            transferArrayItem(event.previousContainer.data,
+                event.container.data,
+                event.previousIndex,
+                event.currentIndex);
+        }
+    }
+
+    onSubmit() {
+        let arrIndexingModels: any[] = [];
+        this.fieldCategories.forEach(category => {
+            arrIndexingModels = arrIndexingModels.concat(this['indexingModels_' + category]);
+        });
+    }
+
+    removeItem(arrTarget: string, item: any, index: number) {
+        item.mandatory = false;
+        if (item.identifier.indexOf('indexingCustomField') > -1) {
+            this.availableCustomFields.push(item);
+            this[arrTarget].splice(index, 1);
+        } else {
+            this.availableFields.push(item);
+            this[arrTarget].splice(index, 1);
+        }
+    }
+
+    getDatas() {
+        let arrIndexingModels: any[] = [];
+        this.fieldCategories.forEach(category => {
+            arrIndexingModels = arrIndexingModels.concat(this['indexingModels_' + category]);
+        });
+        return arrIndexingModels;
+    }
+
+    getAvailableFields() {
+        return this.availableFields;
+    }
+
+    getAvailableCustomFields() {
+        return this.availableCustomFields;
+    }
+
+    isModified() {
+        let state = false;
+        let compare: string = '';
+        let compareClone: string = '';
+
+        this.fieldCategories.forEach(category => {
+
+            compare = JSON.stringify((this['indexingModels_' + category]));
+            compareClone = JSON.stringify((this['indexingModels_' + category + 'Clone']));
+
+            if (compare !== compareClone) {
+                state = true;
+            }
+        });
+        return state;
+    }
+
+    setModification() {
+        this.fieldCategories.forEach(element => {
+            this['indexingModels_' + element + 'Clone'] = JSON.parse(JSON.stringify(this['indexingModels_' + element]));
+        });
+    }
+
+    cancelModification() {
+        this.fieldCategories.forEach(element => {
+            this['indexingModels_' + element] = JSON.parse(JSON.stringify(this['indexingModels_' + element + 'Clone']));
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts
index d14206164bfc2eb08098bc14e4e6b2afa2ed1b6f..66c28d9e3d38f446e6fc403a2b800c23d6d2076a 100755
--- a/src/frontend/lang/lang-en.ts
+++ b/src/frontend/lang/lang-en.ts
@@ -1101,4 +1101,14 @@ export const LANG_EN = {
     "privateFolder" : "Private folder",
     "visibleBy" : "Visible by",
     "folderInformations" : "Folder Informations",
+    "process" : "Process",
+    "modelName" : "Model name",
+    "defaultModel" : "Default model",
+    "indexingForm" : "Indexing form",
+    "availableFields" : "Available field(s)",
+    "availableCustomFields" : "Available custom field(s)",
+    "indexingModel" : "Indexing model",
+    "indexingModelModification" : "Indexing model modification",
+    "mandatoryField" : "Mandatory field",
+    "optionalField" : "Optional field",
 };
diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts
index 0628cb7dfda8b5c172f4019ac891c6cdd8b0a5a5..e430fd3cd83dd474ee5a095e5cd81ce46ccca6c8 100755
--- a/src/frontend/lang/lang-fr.ts
+++ b/src/frontend/lang/lang-fr.ts
@@ -1138,4 +1138,14 @@ export const LANG_FR = {
     "privateFolder" : "Dossier privé",
     "visibleBy" : "Visible par",
     "folderInformations" : "Informations du dossier",
+    "process" : "Traitement",
+    "modelName" : "Nom du modèle",
+    "defaultModel" : "Modèle par défaut",
+    "indexingForm" : "Formulaire d'enregistrement",
+    "availableFields" : "Champ(s) disponible(s)",
+    "availableCustomFields" : "Champ(s) personnalisé(s) disponible(s)",
+    "indexingModel" : "Modèle d'enregistrement",
+    "indexingModelModification" : "Modification du modèle d'enregistrement",
+    "mandatoryField" : "Champ obligatoire",
+    "optionalField" : "Champ optionnel",
 };
diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts
index d3cf727d3aaca341465b7766d7fba1f41b08bede..16e39b44ef64568a3c6534505abda8715ed6c371 100755
--- a/src/frontend/lang/lang-nl.ts
+++ b/src/frontend/lang/lang-nl.ts
@@ -1127,4 +1127,14 @@ export const LANG_NL = {
     "privateFolder" : "Private folder", //_TO_TRANSLATE
     "visibleBy" : "Visible by", //_TO_TRANSLATE
     "folderInformations" : "Folder Informations", //_TO_TRANSLATE
+    "process" : "Process", //_TO_TRANSLATE
+    "modelName" : "Model name", //_TO_TRANSLATE
+    "defaultModel" : "Default model", //_TO_TRANSLATE
+    "indexingForm" : "Indexing form", //_TO_TRANSLATE
+    "availableFields" : "Available field(s)", //_TO_TRANSLATE
+    "availableCustomFields" : "Available custom field(s)", //_TO_TRANSLATE
+    "indexingModel" : "Indexing model", //_TO_TRANSLATE
+    "indexingModelModification" : "Indexing model modification", //_TO_TRANSLATE
+    "mandatoryField" : "Mandatory field", //_TO_TRANSLATE
+    "optionalField" : "Optional field", //_TO_TRANSLATE
 };