From 7db543fc820295ab54da99506f5a0065695ea5c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Agneray?= <francois.agneray@lam.fr>
Date: Wed, 28 Sep 2022 21:12:43 +0200
Subject: [PATCH] #76 => done

---
 .../components/instance-form.component.html   | 130 ++++++++-
 .../components/instance-form.component.ts     |  11 +
 .../app/instance/instance.component.spec.ts   |  11 +
 client/src/app/instance/instance.component.ts |  16 ++
 .../components/progress-bar.component.spec.ts |  22 ++
 .../result/datatable.component.html           |  14 +-
 .../effects/search-multiple.effects.spec.ts   |  22 ++
 .../app/metamodel/models/instance.model.ts    |  21 +-
 client/src/test-data.ts                       |  33 +++
 conf-dev/create-db.sh                         |   2 +-
 .../__CG__AppEntityInstance.php               | 246 +++++++++++++++++-
 server/src/Action/InstanceAction.php          |  22 ++
 server/src/Action/InstanceListAction.php      |  22 ++
 server/src/Entity/Instance.php                | 212 +++++++++++++++
 server/tests/Action/InstanceActionTest.php    |  11 +
 .../tests/Action/InstanceListActionTest.php   |  13 +-
 16 files changed, 779 insertions(+), 29 deletions(-)

diff --git a/client/src/app/admin/instance/components/instance-form.component.html b/client/src/app/admin/instance/components/instance-form.component.html
index ab93e4e9..39aa7358 100644
--- a/client/src/app/admin/instance/components/instance-form.component.html
+++ b/client/src/app/admin/instance/components/instance-form.component.html
@@ -145,6 +145,14 @@
                     <input type="text" class="form-control" id="navbar_color_href_input" [value]="form.value.navbar_color_href" formControlName="navbar_color_href">
                 </div>
             </div>
+            <div class="custom-control custom-switch mb-2">
+                <input class="custom-control-input" type="checkbox" id="back_to_portal" name="back_to_portal" formControlName="back_to_portal">
+                <label class="custom-control-label" for="back_to_portal">Back to portal</label>
+            </div>
+            <div class="custom-control custom-switch mb-2">
+                <input class="custom-control-input" type="checkbox" id="user_menu_enabled" name="user_menu_enabled" formControlName="user_menu_enabled">
+                <label class="custom-control-label" for="user_menu_enabled">User menu enabled</label>
+            </div>
         </accordion-group>
         <accordion-group heading="Design footer" [isOpen]="false">
             <div class="form-row">
@@ -341,7 +349,7 @@
                     <input class="form-control" type="color" id="result_header_text_color_picker" [value]="form.value.result_header_text_color" formControlName="result_header_text_color">
                 </div>
                 <div class="form-group col-md-6">
-                    <label for="result_header_text_color_input">Result header text color  (value)</label>
+                    <label for="result_header_text_color_input">Result header text color (value)</label>
                     <input type="text" class="form-control" id="result_header_text_color_input" [value]="form.value.result_header_text_color" formControlName="result_header_text_color">
                 </div>
             </div>
@@ -351,7 +359,7 @@
                     <input class="form-control" type="color" id="result_header_btn_color_picker" [value]="form.value.result_header_btn_color" formControlName="result_header_btn_color">
                 </div>
                 <div class="form-group col-md-6">
-                    <label for="result_header_btn_color_input">Result header btn color  (value)</label>
+                    <label for="result_header_btn_color_input">Result header btn color (value)</label>
                     <input type="text" class="form-control" id="result_header_btn_color_input" [value]="form.value.result_header_btn_color" formControlName="result_header_btn_color">
                 </div>
             </div>
@@ -361,7 +369,7 @@
                     <input class="form-control" type="color" id="result_header_btn_hover_color_picker" [value]="form.value.result_header_btn_hover_color" formControlName="result_header_btn_hover_color">
                 </div>
                 <div class="form-group col-md-6">
-                    <label for="result_header_btn_hover_color_input">Result header btn hover color  (value)</label>
+                    <label for="result_header_btn_hover_color_input">Result header btn hover color (value)</label>
                     <input type="text" class="form-control" id="result_header_btn_hover_color_input" [value]="form.value.result_header_btn_hover_color" formControlName="result_header_btn_hover_color">
                 </div>
             </div>
@@ -371,23 +379,121 @@
                     <input class="form-control" type="color" id="result_header_btn_text_color_picker" [value]="form.value.result_header_btn_text_color" formControlName="result_header_btn_text_color">
                 </div>
                 <div class="form-group col-md-6">
-                    <label for="result_header_btn_text_color_input">Result header btn text color  (value)</label>
+                    <label for="result_header_btn_text_color_input">Result header btn text color (value)</label>
                     <input type="text" class="form-control" id="result_header_btn_text_color_input" [value]="form.value.result_header_btn_text_color" formControlName="result_header_btn_text_color">
                 </div>
             </div>
         </accordion-group>
-        <accordion-group heading="Functionalities" [isOpen]="false">
+        <accordion-group heading="Design result datatable" [isOpen]="false">
             <div class="custom-control custom-switch mb-2">
-                <input class="custom-control-input" type="checkbox" id="samp_enabled" name="samp_enabled" formControlName="samp_enabled">
-                <label class="custom-control-label" for="samp_enabled">Samp enabled</label>
+                <input class="custom-control-input" type="checkbox" id="result_datatable_bordered" name="result_datatable_bordered" formControlName="result_datatable_bordered">
+                <label class="custom-control-label" for="result_datatable_bordered">Result datatable bordered</label>
             </div>
-            <div class="custom-control custom-switch mb-2">
-                <input class="custom-control-input" type="checkbox" id="back_to_portal" name="back_to_portal" formControlName="back_to_portal">
-                <label class="custom-control-label" for="back_to_portal">Back to portal</label>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_border_color_picker">Result datatable border color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_border_color_picker" [value]="form.value.result_datatable_border_color" formControlName="result_datatable_border_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_border_color_input">Result datatable border color color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_border_color_input" [value]="form.value.result_datatable_border_color" formControlName="result_datatable_border_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_header_background_color_picker">Result datatable header background color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_header_background_color_picker" [value]="form.value.result_datatable_header_background_color" formControlName="result_datatable_header_background_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_header_background_color_input">Result datatable header background color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_header_background_color_input" [value]="form.value.result_datatable_header_background_color" formControlName="result_datatable_header_background_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_header_text_color_picker">Result datatable header text color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_header_text_color_picker" [value]="form.value.result_datatable_header_text_color" formControlName="result_datatable_header_text_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_header_text_color_input">Result datatable header text color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_header_text_color_input" [value]="form.value.result_datatable_header_text_color" formControlName="result_datatable_header_text_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_rows_background_color_picker">Result datatable rows background color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_rows_background_color_picker" [value]="form.value.result_datatable_rows_background_color" formControlName="result_datatable_rows_background_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_rows_background_color_input">Result datatable rows background color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_rows_background_color_input" [value]="form.value.result_datatable_rows_background_color" formControlName="result_datatable_rows_background_color">
+                </div>
             </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_rows_text_color_picker">Result datatable rows text color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_rows_text_color_picker" [value]="form.value.result_datatable_rows_text_color" formControlName="result_datatable_rows_text_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_rows_text_color_input">Result datatable rows text color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_rows_text_color_input" [value]="form.value.result_datatable_rows_text_color" formControlName="result_datatable_rows_text_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_sorted_color_picker">Result datatable sorted color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_sorted_color_picker" [value]="form.value.result_datatable_sorted_color" formControlName="result_datatable_sorted_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_sorted_color_input">Result datatable sorted color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_sorted_color_input" [value]="form.value.result_datatable_sorted_color" formControlName="result_datatable_sorted_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_sorted_active_color_picker">Result datatable sorted active color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_sorted_active_color_picker" [value]="form.value.result_datatable_sorted_active_color" formControlName="result_datatable_sorted_active_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_sorted_active_color_input">Result datatable sorted active color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_sorted_active_color_input" [value]="form.value.result_datatable_sorted_active_color" formControlName="result_datatable_sorted_active_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_link_color_picker">Result datatable link color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_link_color_picker" [value]="form.value.result_datatable_link_color" formControlName="result_datatable_link_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_link_color_input">Result datatable link color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_link_color_input" [value]="form.value.result_datatable_link_color" formControlName="result_datatable_link_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_link_hover_color_picker">Result datatable link hover color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_link_hover_color_picker" [value]="form.value.result_datatable_link_hover_color" formControlName="result_datatable_link_hover_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_link_hover_color_input">Result datatable link hover color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_link_hover_color_input" [value]="form.value.result_datatable_link_hover_color" formControlName="result_datatable_link_hover_color">
+                </div>
+            </div>
+            <div class="form-row">
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_rows_selected_color_picker">Result datatable rows selected color (picker)</label>
+                    <input class="form-control" type="color" id="result_datatable_rows_selected_color_picker" [value]="form.value.result_datatable_rows_selected_color" formControlName="result_datatable_rows_selected_color">
+                </div>
+                <div class="form-group col-md-6">
+                    <label for="result_datatable_rows_selected_color_input">Result datatable rows selected color (value)</label>
+                    <input type="text" class="form-control" id="result_datatable_rows_selected_color_input" [value]="form.value.result_datatable_rows_selected_color" formControlName="result_datatable_rows_selected_color">
+                </div>
+            </div>
+        </accordion-group>
+        <accordion-group heading="Functionalities" [isOpen]="false">
             <div class="custom-control custom-switch mb-2">
-                <input class="custom-control-input" type="checkbox" id="user_menu_enabled" name="user_menu_enabled" formControlName="user_menu_enabled">
-                <label class="custom-control-label" for="user_menu_enabled">User menu enabled</label>
+                <input class="custom-control-input" type="checkbox" id="samp_enabled" name="samp_enabled" formControlName="samp_enabled">
+                <label class="custom-control-label" for="samp_enabled">Samp enabled</label>
             </div>
             <div class="custom-control custom-switch mb-2">
                 <input class="custom-control-input" type="checkbox" id="search_by_criteria_allowed" name="search_by_criteria_allowed" formControlName="search_by_criteria_allowed" (change)="checkDisableSearchByCriteriaAllowed()">
diff --git a/client/src/app/admin/instance/components/instance-form.component.ts b/client/src/app/admin/instance/components/instance-form.component.ts
index 74b37c56..4d8ee67c 100644
--- a/client/src/app/admin/instance/components/instance-form.component.ts
+++ b/client/src/app/admin/instance/components/instance-form.component.ts
@@ -68,6 +68,17 @@ export class InstanceFormComponent implements OnInit {
         result_header_btn_color: new UntypedFormControl('#007BFF'),
         result_header_btn_hover_color: new UntypedFormControl('#0069D9'),
         result_header_btn_text_color: new UntypedFormControl('#FFFFFF'),
+        result_datatable_bordered: new UntypedFormControl(true),
+        result_datatable_border_color: new UntypedFormControl('#DEE2E6'),
+        result_datatable_header_background_color: new UntypedFormControl('#FFFFFF'),
+        result_datatable_header_text_color: new UntypedFormControl('#000000'),
+        result_datatable_rows_background_color: new UntypedFormControl('#FFFFFF'),
+        result_datatable_rows_text_color: new UntypedFormControl('#000000'),
+        result_datatable_sorted_color: new UntypedFormControl('#C5C5C5'),
+        result_datatable_sorted_active_color: new UntypedFormControl('#000000'),
+        result_datatable_link_color: new UntypedFormControl('#007BFF'),
+        result_datatable_link_hover_color: new UntypedFormControl('#0056B3'),
+        result_datatable_rows_selected_color: new UntypedFormControl('#7AC29A'),
         samp_enabled: new UntypedFormControl(true),
         back_to_portal: new UntypedFormControl(true),
         user_menu_enabled: new UntypedFormControl(true),
diff --git a/client/src/app/instance/instance.component.spec.ts b/client/src/app/instance/instance.component.spec.ts
index e0ab549d..532d50d6 100644
--- a/client/src/app/instance/instance.component.spec.ts
+++ b/client/src/app/instance/instance.component.spec.ts
@@ -117,6 +117,17 @@ describe('[Instance] InstanceComponent', () => {
             result_header_btn_color: '#007BFF',
             result_header_btn_hover_color: '#0069D9',
             result_header_btn_text_color: '#FFFFFF',
+            result_datatable_bordered: true,
+            result_datatable_border_color: '#DEE2E6',
+            result_datatable_header_background_color: '#FFFFFF',
+            result_datatable_header_text_color: '#000000',
+            result_datatable_rows_background_color: '#FFFFFF',
+            result_datatable_rows_text_color: '#000000',
+            result_datatable_sorted_color: '#C5C5C5',
+            result_datatable_sorted_active_color: '#000000',
+            result_datatable_link_color: '#007BFF',
+            result_datatable_link_hover_color: '#0056B3',
+            result_datatable_rows_selected_color: '#7AC29A',
             samp_enabled: true,
             back_to_portal: true,
             user_menu_enabled: true,
diff --git a/client/src/app/instance/instance.component.ts b/client/src/app/instance/instance.component.ts
index e09af02e..d2ed0b62 100644
--- a/client/src/app/instance/instance.component.ts
+++ b/client/src/app/instance/instance.component.ts
@@ -136,6 +136,22 @@ export class InstanceComponent implements OnInit, OnDestroy {
                         'border-color': instance.result_header_btn_hover_color,
                         'color': instance.result_header_btn_text_color
                     });
+
+                    if (instance.result_datatable_bordered) {
+                        this.style.setStyle('#datatable.table-bordered th, #datatable.table-bordered td', 'border', `1px solid ${instance.result_datatable_border_color}`);
+                        this.style.setStyle('#datatable.table-bordered thead th', 'border-bottom', `2px solid ${instance.result_datatable_border_color}`);
+                    } else {
+                        this.style.setStyle('#datatable.table th, #datatable.table td', 'border-top', `1px solid ${instance.result_datatable_border_color}`);
+                        this.style.setStyle('#datatable.table thead th', 'border-bottom', `2px solid ${instance.result_datatable_border_color}`);
+                    }
+                    
+                    this.style.setStyle('#datatable.table a', 'color', instance.result_datatable_link_color);
+                    this.style.setStyle('#datatable.table a', 'text-decoration', 'none');
+                    this.style.setStyle('#datatable.table a.btn-outline-primary', 'border-color', instance.result_datatable_link_color);
+                    this.style.setStyle('#datatable.table a:hover', 'color', instance.result_datatable_link_hover_color);
+                    this.style.setStyle('#datatable.table a.btn-outline-primary:hover', 'color', instance.result_datatable_link_hover_color);
+                    this.style.setStyle('#datatable.table a.btn-outline-primary:hover', 'background-color', instance.result_datatable_rows_background_color);
+                    this.style.setStyle('#datatable.table a.btn-outline-primary:hover', 'border-color', instance.result_datatable_link_hover_color);
                 }
             }
         });
diff --git a/client/src/app/instance/search/components/progress-bar.component.spec.ts b/client/src/app/instance/search/components/progress-bar.component.spec.ts
index 86d7cf0c..5934b27f 100644
--- a/client/src/app/instance/search/components/progress-bar.component.spec.ts
+++ b/client/src/app/instance/search/components/progress-bar.component.spec.ts
@@ -90,6 +90,17 @@ describe('[Instance][Search][Component] ProgressBarComponent', () => {
             result_header_btn_color: '#007BFF',
             result_header_btn_hover_color: '#0069D9',
             result_header_btn_text_color: '#FFFFFF',
+            result_datatable_bordered: true,
+            result_datatable_border_color: '#DEE2E6',
+            result_datatable_header_background_color: '#FFFFFF',
+            result_datatable_header_text_color: '#000000',
+            result_datatable_rows_background_color: '#FFFFFF',
+            result_datatable_rows_text_color: '#000000',
+            result_datatable_sorted_color: '#C5C5C5',
+            result_datatable_sorted_active_color: '#000000',
+            result_datatable_link_color: '#007BFF',
+            result_datatable_link_hover_color: '#0056B3',
+            result_datatable_rows_selected_color: '#7AC29A',
             samp_enabled: true,
             back_to_portal: true,
             user_menu_enabled: true,
@@ -152,6 +163,17 @@ describe('[Instance][Search][Component] ProgressBarComponent', () => {
             result_header_btn_color: '#007BFF',
             result_header_btn_hover_color: '#0069D9',
             result_header_btn_text_color: '#FFFFFF',
+            result_datatable_bordered: true,
+            result_datatable_border_color: '#DEE2E6',
+            result_datatable_header_background_color: '#FFFFFF',
+            result_datatable_header_text_color: '#000000',
+            result_datatable_rows_background_color: '#FFFFFF',
+            result_datatable_rows_text_color: '#000000',
+            result_datatable_sorted_color: '#C5C5C5',
+            result_datatable_sorted_active_color: '#000000',
+            result_datatable_link_color: '#007BFF',
+            result_datatable_link_hover_color: '#0056B3',
+            result_datatable_rows_selected_color: '#7AC29A',
             samp_enabled: true,
             back_to_portal: true,
             user_menu_enabled: true,
diff --git a/client/src/app/instance/search/components/result/datatable.component.html b/client/src/app/instance/search/components/result/datatable.component.html
index 9b135b62..732e19d4 100644
--- a/client/src/app/instance/search/components/result/datatable.component.html
+++ b/client/src/app/instance/search/components/result/datatable.component.html
@@ -1,14 +1,14 @@
 <app-spinner *ngIf="dataIsLoading"></app-spinner>
 
 <div class="table-responsive" *ngIf="dataIsLoaded">
-    <table id="datatable" class="table table-bordered table-hover" aria-describedby="List of results">
+    <table id="datatable" class="table table-hover" [ngClass]="{'table-bordered': instance.result_datatable_bordered}" aria-describedby="List of results">
         <thead>
-            <tr>
+            <tr [ngStyle]="{ 'background-color': instance.result_datatable_header_background_color, 'color': instance.result_datatable_header_text_color }">
                 <th *ngIf="dataset.datatable_selectable_rows" scope="col" class="select">#</th>
                 <th *ngFor="let attribute of getOutputList()" scope="col" draggable="true" class="datatable-title">
                     <app-attribute-label [label]="attribute.label" [description]="attribute.description"></app-attribute-label>
                     &nbsp;
-                    <span *ngIf="attribute.id === sortedCol && attribute.order_by" class="pl-2" class="clickable" (click)="sort(attribute.id)">
+                    <span *ngIf="attribute.id === sortedCol && attribute.order_by" class="pl-2" class="clickable" (click)="sort(attribute.id)" [ngStyle]="{ 'color': instance.result_datatable_sorted_active_color, 'background-color': instance.result_datatable_header_background_color }">
                         <span [ngClass]="{'active': sortedOrder === 'a', 'inactive': sortedOrder === 'd'}">
                             <span class="fas fa-fw fa-sort-amount-down-alt"></span>
                         </span>
@@ -17,10 +17,10 @@
                         </span>
                     </span>
                     <span *ngIf="attribute.id !== sortedCol && attribute.order_by" class="pl-2" class="clickable" (click)="sort(attribute.id)">
-                        <span class="unsorted">
+                        <span class="unsorted" [ngStyle]="{ 'color': instance.result_datatable_sorted_color }">
                             <span class="fas fa-fw fa-arrows-alt-v"></span>
                         </span>
-                        <span class="on-hover">
+                        <span class="on-hover" [ngStyle]="{ 'color': instance.result_datatable_sorted_color, 'background-color': instance.result_datatable_header_background_color }">
                             <span class="fas fa-fw fa-sort-amount-down-alt"></span>
                         </span>
                     </span>
@@ -28,7 +28,7 @@
             </tr>
         </thead>
         <tbody>
-            <tr *ngFor="let datum of data" [ngStyle]="{'background-color': datumSelectedInPlot(datum) ? instance.design_color : ''}">
+            <tr *ngFor="let datum of data" [ngStyle]="{'background-color': datumSelectedInPlot(datum) ? instance.result_datatable_rows_selected_color : instance.result_datatable_rows_background_color, 'color': instance.result_datatable_rows_text_color }">
                 <td *ngIf="dataset.datatable_selectable_rows" class="data-selected align-middle"
                     (click)="toggleSelection(datum)">
                     <button class="btn btn-block text-left p-0 m-0">
@@ -36,7 +36,7 @@
                             <span class="far fa-square fa-lg text-secondary"></span>
                         </span>
                         <span *ngIf="isSelected(datum)">
-                            <span class="fas fa-check-square fa-lg" [ngStyle]="{ 'color': instance.design_color }"></span>
+                            <span class="fas fa-check-square fa-lg" [ngStyle]="{ 'color': instance.result_datatable_rows_selected_color }"></span>
                         </span>
                     </button>
                 </td>
diff --git a/client/src/app/instance/store/effects/search-multiple.effects.spec.ts b/client/src/app/instance/store/effects/search-multiple.effects.spec.ts
index d96b567c..b1c85d29 100644
--- a/client/src/app/instance/store/effects/search-multiple.effects.spec.ts
+++ b/client/src/app/instance/store/effects/search-multiple.effects.spec.ts
@@ -172,6 +172,17 @@ describe('[Instance][Store] SearchMultipleEffects', () => {
                     result_header_btn_color: '#007BFF',
                     result_header_btn_hover_color: '#0069D9',
                     result_header_btn_text_color: '#FFFFFF',
+                    result_datatable_bordered: true,
+                    result_datatable_border_color: '#DEE2E6',
+                    result_datatable_header_background_color: '#FFFFFF',
+                    result_datatable_header_text_color: '#000000',
+                    result_datatable_rows_background_color: '#FFFFFF',
+                    result_datatable_rows_text_color: '#000000',
+                    result_datatable_sorted_color: '#C5C5C5',
+                    result_datatable_sorted_active_color: '#000000',
+                    result_datatable_link_color: '#007BFF',
+                    result_datatable_link_hover_color: '#0056B3',
+                    result_datatable_rows_selected_color: '#7AC29A',
                     samp_enabled: true,
                     back_to_portal: true,
                     user_menu_enabled: true,
@@ -277,6 +288,17 @@ describe('[Instance][Store] SearchMultipleEffects', () => {
                     result_header_btn_color: '#007BFF',
                     result_header_btn_hover_color: '#0069D9',
                     result_header_btn_text_color: '#FFFFFF',
+                    result_datatable_bordered: true,
+                    result_datatable_border_color: '#DEE2E6',
+                    result_datatable_header_background_color: '#FFFFFF',
+                    result_datatable_header_text_color: '#000000',
+                    result_datatable_rows_background_color: '#FFFFFF',
+                    result_datatable_rows_text_color: '#000000',
+                    result_datatable_sorted_color: '#C5C5C5',
+                    result_datatable_sorted_active_color: '#000000',
+                    result_datatable_link_color: '#007BFF',
+                    result_datatable_link_hover_color: '#0056B3',
+                    result_datatable_rows_selected_color: '#7AC29A',
                     samp_enabled: true,
                     back_to_portal: true,
                     user_menu_enabled: true,
diff --git a/client/src/app/metamodel/models/instance.model.ts b/client/src/app/metamodel/models/instance.model.ts
index 9af4a6be..e472c380 100644
--- a/client/src/app/metamodel/models/instance.model.ts
+++ b/client/src/app/metamodel/models/instance.model.ts
@@ -50,11 +50,22 @@ export interface Instance {
     progress_bar_circle_icon_color: string;
     progress_bar_circle_icon_active_color: string;
     progress_bar_text_color: string;
-    result_header_background_color: string,
-    result_header_text_color: string,
-    result_header_btn_color: string,
-    result_header_btn_hover_color: string,
-    result_header_btn_text_color: string,
+    result_header_background_color: string;
+    result_header_text_color: string;
+    result_header_btn_color: string;
+    result_header_btn_hover_color: string;
+    result_header_btn_text_color: string;
+    result_datatable_bordered: boolean;
+    result_datatable_border_color: string;
+    result_datatable_header_background_color: string;
+    result_datatable_header_text_color: string;
+    result_datatable_rows_background_color: string;
+    result_datatable_rows_text_color: string;
+    result_datatable_sorted_color: string,
+    result_datatable_sorted_active_color: string,
+    result_datatable_link_color: string,
+    result_datatable_link_hover_color: string,
+    result_datatable_rows_selected_color: string,
     samp_enabled: boolean;
     back_to_portal: boolean;
     user_menu_enabled: boolean;
diff --git a/client/src/test-data.ts b/client/src/test-data.ts
index 50e232f2..22c003c1 100644
--- a/client/src/test-data.ts
+++ b/client/src/test-data.ts
@@ -87,6 +87,17 @@ export const INSTANCE_LIST: Instance[] = [
         result_header_btn_color: '#007BFF',
         result_header_btn_hover_color: '#0069D9',
         result_header_btn_text_color: '#FFFFFF',
+        result_datatable_bordered: true,
+        result_datatable_border_color: '#DEE2E6',
+        result_datatable_header_background_color: '#FFFFFF',
+        result_datatable_header_text_color: '#000000',
+        result_datatable_rows_background_color: '#FFFFFF',
+        result_datatable_rows_text_color: '#000000',
+        result_datatable_sorted_color: '#C5C5C5',
+        result_datatable_sorted_active_color: '#000000',
+        result_datatable_link_color: '#007BFF',
+        result_datatable_link_hover_color: '#0056B3',
+        result_datatable_rows_selected_color: '#7AC29A',
         samp_enabled: true,
         back_to_portal: true,
         user_menu_enabled: true,
@@ -143,6 +154,17 @@ export const INSTANCE_LIST: Instance[] = [
         result_header_btn_color: '#007BFF',
         result_header_btn_hover_color: '#0069D9',
         result_header_btn_text_color: '#FFFFFF',
+        result_datatable_bordered: true,
+        result_datatable_border_color: '#DEE2E6',
+        result_datatable_header_background_color: '#FFFFFF',
+        result_datatable_header_text_color: '#000000',
+        result_datatable_rows_background_color: '#FFFFFF',
+        result_datatable_rows_text_color: '#000000',
+        result_datatable_sorted_color: '#C5C5C5',
+        result_datatable_sorted_active_color: '#000000',
+        result_datatable_link_color: '#007BFF',
+        result_datatable_link_hover_color: '#0056B3',
+        result_datatable_rows_selected_color: '#7AC29A',
         samp_enabled: true,
         back_to_portal: true,
         user_menu_enabled: true,
@@ -201,6 +223,17 @@ export const INSTANCE: Instance = {
     result_header_btn_color: '#007BFF',
     result_header_btn_hover_color: '#0069D9',
     result_header_btn_text_color: '#FFFFFF',
+    result_datatable_bordered: true,
+    result_datatable_border_color: '#DEE2E6',
+    result_datatable_header_background_color: '#FFFFFF',
+    result_datatable_header_text_color: '#000000',
+    result_datatable_rows_background_color: '#FFFFFF',
+    result_datatable_rows_text_color: '#000000',
+    result_datatable_sorted_color: '#C5C5C5',
+    result_datatable_sorted_active_color: '#000000',
+    result_datatable_link_color: '#007BFF',
+    result_datatable_link_hover_color: '#0056B3',
+    result_datatable_rows_selected_color: '#7AC29A',
     samp_enabled: true,
     back_to_portal: true,
     user_menu_enabled: true,
diff --git a/conf-dev/create-db.sh b/conf-dev/create-db.sh
index cbb6f608..c89751cb 100644
--- a/conf-dev/create-db.sh
+++ b/conf-dev/create-db.sh
@@ -8,7 +8,7 @@ set -e
 curl -d '{"label":"Test","dbname":"anis_test","dbtype":"pdo_pgsql","dbhost":"db","dbport":5432,"dblogin":"anis","dbpassword":"anis"}' --header 'Content-Type: application/json' -X POST http://localhost/database
 
 # Add default instance
-curl -d '{"name":"default","label":"Default instance","description":"Instance for the test","scientific_manager":"M. Durand","instrument":"Multiple","wavelength_domain":"Visible imaging / Spectroscopy","display":10,"data_path":"\/DEFAULT","files_path":"\/INSTANCE_FILES","public":true,"portal_logo":"","design_color":"#7AC29A","design_background_color":"#ffffff","design_logo":"/logo.png","design_favicon":"/favicon.ico","navbar_background_color":"#F8F9FA","navbar_border_bottom_color":"#DEE2E6","navbar_color_href":"#000000","footer_background_color":"#F8F9FA","footer_border_top_color":"#DEE2E6","footer_text_color":"#000000","family_border_color":"#DFDFDF","family_header_background_color":"#F7F7F7","family_title_color":"#007BFF","family_title_bold":false,"family_background_color":"#FFFFFF","family_color":"#212529","progress_bar_title":"Dataset search","progress_bar_title_color":"#000000","progress_bar_subtitle":"Select a dataset, add criteria, select output columns and display the result.","progress_bar_subtitle_color":"#6C757D","progress_bar_color":"#E9ECEF","progress_bar_active_color":"#7AC29A","progress_bar_circle_color":"#FFFFFF","progress_bar_circle_icon_color":"#CCCCCC","progress_bar_circle_icon_active_color":"#FFFFFF","progress_bar_text_color":"#91B2BF","result_header_background_color":"#E9ECEF","result_header_text_color":"#000000","result_header_btn_color":"#007BFF","result_header_btn_hover_color":"#0069D9","result_header_btn_text_color":"#FFFFFF","samp_enabled":true,"back_to_portal":true,"user_menu_enabled":true,"search_by_criteria_allowed":true,"search_by_criteria_label":"Search","search_multiple_allowed":false,"search_multiple_label":"Search multiple","search_multiple_all_datasets_selected":false,"documentation_allowed":false,"documentation_label":"Documentation"}' --header 'Content-Type: application/json' -X POST http://localhost/instance
+curl -d '{"name":"default","label":"Default instance","description":"Instance for the test","scientific_manager":"M. Durand","instrument":"Multiple","wavelength_domain":"Visible imaging / Spectroscopy","display":10,"data_path":"\/DEFAULT","files_path":"\/INSTANCE_FILES","public":true,"portal_logo":"","design_color":"#7AC29A","design_background_color":"#ffffff","design_logo":"/logo.png","design_favicon":"/favicon.ico","navbar_background_color":"#F8F9FA","navbar_border_bottom_color":"#DEE2E6","navbar_color_href":"#000000","footer_background_color":"#F8F9FA","footer_border_top_color":"#DEE2E6","footer_text_color":"#000000","family_border_color":"#DFDFDF","family_header_background_color":"#F7F7F7","family_title_color":"#007BFF","family_title_bold":false,"family_background_color":"#FFFFFF","family_color":"#212529","progress_bar_title":"Dataset search","progress_bar_title_color":"#000000","progress_bar_subtitle":"Select a dataset, add criteria, select output columns and display the result.","progress_bar_subtitle_color":"#6C757D","progress_bar_color":"#E9ECEF","progress_bar_active_color":"#7AC29A","progress_bar_circle_color":"#FFFFFF","progress_bar_circle_icon_color":"#CCCCCC","progress_bar_circle_icon_active_color":"#FFFFFF","progress_bar_text_color":"#91B2BF","result_header_background_color":"#E9ECEF","result_header_text_color":"#000000","result_header_btn_color":"#007BFF","result_header_btn_hover_color":"#0069D9","result_header_btn_text_color":"#FFFFFF","result_datatable_bordered":true,"result_datatable_border_color":"#DEE2E6","result_datatable_header_background_color":"#FFFFFF","result_datatable_header_text_color":"#000000","result_datatable_rows_background_color":"#FFFFFF","result_datatable_rows_text_color":"#000000","result_datatable_sorted_color":"#C5C5C5","result_datatable_sorted_active_color":"#000000","result_datatable_link_color":"#007BFF","result_datatable_link_hover_color":"#0056B3","result_datatable_rows_selected_color":"#7AC29A","samp_enabled":true,"back_to_portal":true,"user_menu_enabled":true,"search_by_criteria_allowed":true,"search_by_criteria_label":"Search","search_multiple_allowed":false,"search_multiple_label":"Search multiple","search_multiple_all_datasets_selected":false,"documentation_allowed":false,"documentation_label":"Documentation"}' --header 'Content-Type: application/json' -X POST http://localhost/instance
 
 # Add dataset families
 curl -d '{"label":"Default dataset family","display":10,"opened":true}' --header 'Content-Type: application/json' -X POST http://localhost/instance/default/dataset-family
diff --git a/server/doctrine-proxy/__CG__AppEntityInstance.php b/server/doctrine-proxy/__CG__AppEntityInstance.php
index 567a7eaa..697ea08e 100644
--- a/server/doctrine-proxy/__CG__AppEntityInstance.php
+++ b/server/doctrine-proxy/__CG__AppEntityInstance.php
@@ -67,10 +67,10 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy
     public function __sleep()
     {
         if ($this->__isInitialized__) {
-            return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'navbarBackgroundColor', 'navbarBorderBottomColor', 'navbarColorHref', 'footerBackgroundColor', 'footerBorderTopColor', 'footerTextColor', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyBackgroundColor', 'familyColor', 'progressBarTitle', 'progressBarTitleColor', 'progressBarSubtitle', 'progressBarSubtitleColor', 'progressBarColor', 'progressBarActiveColor', 'progressBarCircleColor', 'progressBarCircleIconColor', 'progressBarCircleIconActiveColor', 'progressBarTextColor', 'resultHeaderBackgroundColor', 'resultHeaderTextColor', 'resultHeaderBtnColor', 'resultHeaderBtnHoverColor', 'resultHeaderBtnTextColor', 'sampEnabled', 'backToPortal', 'userMenuEnabled', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies'];
+            return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'navbarBackgroundColor', 'navbarBorderBottomColor', 'navbarColorHref', 'footerBackgroundColor', 'footerBorderTopColor', 'footerTextColor', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyBackgroundColor', 'familyColor', 'progressBarTitle', 'progressBarTitleColor', 'progressBarSubtitle', 'progressBarSubtitleColor', 'progressBarColor', 'progressBarActiveColor', 'progressBarCircleColor', 'progressBarCircleIconColor', 'progressBarCircleIconActiveColor', 'progressBarTextColor', 'resultHeaderBackgroundColor', 'resultHeaderTextColor', 'resultHeaderBtnColor', 'resultHeaderBtnHoverColor', 'resultHeaderBtnTextColor', 'resultDatatableBordered', 'resultDatatableBorderColor', 'resultDatatableHeaderBackgroundColor', 'resultDatatableHeaderTextColor', 'resultDatatableRowsBackgroundColor', 'resultDatatableRowsTextColor', 'resultDatatableSortedColor', 'resultDatatableSortedActiveColor', 'resultDatatableLinkColor', 'resultDatatableLinkHoverColor', 'resultDatatableRowsSelectedColor', 'sampEnabled', 'backToPortal', 'userMenuEnabled', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies'];
         }
 
-        return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'navbarBackgroundColor', 'navbarBorderBottomColor', 'navbarColorHref', 'footerBackgroundColor', 'footerBorderTopColor', 'footerTextColor', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyBackgroundColor', 'familyColor', 'progressBarTitle', 'progressBarTitleColor', 'progressBarSubtitle', 'progressBarSubtitleColor', 'progressBarColor', 'progressBarActiveColor', 'progressBarCircleColor', 'progressBarCircleIconColor', 'progressBarCircleIconActiveColor', 'progressBarTextColor', 'resultHeaderBackgroundColor', 'resultHeaderTextColor', 'resultHeaderBtnColor', 'resultHeaderBtnHoverColor', 'resultHeaderBtnTextColor', 'sampEnabled', 'backToPortal', 'userMenuEnabled', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies'];
+        return ['__isInitialized__', 'name', 'label', 'description', 'scientificManager', 'instrument', 'wavelengthDomain', 'display', 'dataPath', 'filesPath', 'public', 'portalLogo', 'designColor', 'designBackgroundColor', 'designLogo', 'designFavicon', 'navbarBackgroundColor', 'navbarBorderBottomColor', 'navbarColorHref', 'footerBackgroundColor', 'footerBorderTopColor', 'footerTextColor', 'familyBorderColor', 'familyHeaderBackgroundColor', 'familyTitleColor', 'familyTitleBold', 'familyBackgroundColor', 'familyColor', 'progressBarTitle', 'progressBarTitleColor', 'progressBarSubtitle', 'progressBarSubtitleColor', 'progressBarColor', 'progressBarActiveColor', 'progressBarCircleColor', 'progressBarCircleIconColor', 'progressBarCircleIconActiveColor', 'progressBarTextColor', 'resultHeaderBackgroundColor', 'resultHeaderTextColor', 'resultHeaderBtnColor', 'resultHeaderBtnHoverColor', 'resultHeaderBtnTextColor', 'resultDatatableBordered', 'resultDatatableBorderColor', 'resultDatatableHeaderBackgroundColor', 'resultDatatableHeaderTextColor', 'resultDatatableRowsBackgroundColor', 'resultDatatableRowsTextColor', 'resultDatatableSortedColor', 'resultDatatableSortedActiveColor', 'resultDatatableLinkColor', 'resultDatatableLinkHoverColor', 'resultDatatableRowsSelectedColor', 'sampEnabled', 'backToPortal', 'userMenuEnabled', 'searchByCriteriaAllowed', 'searchByCriteriaLabel', 'searchMultipleAllowed', 'searchMultipleLabel', 'searchMultipleAllDatasetsSelected', 'documentationAllowed', 'documentationLabel', 'datasetFamilies'];
     }
 
     /**
@@ -1094,6 +1094,248 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy
         return parent::setResultHeaderBtnTextColor($resultHeaderBtnTextColor);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableBordered()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableBordered', []);
+
+        return parent::getResultDatatableBordered();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableBordered($resultDatatableBordered)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableBordered', [$resultDatatableBordered]);
+
+        return parent::setResultDatatableBordered($resultDatatableBordered);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableBorderColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableBorderColor', []);
+
+        return parent::getResultDatatableBorderColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableBorderColor($resultDatatableBorderColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableBorderColor', [$resultDatatableBorderColor]);
+
+        return parent::setResultDatatableBorderColor($resultDatatableBorderColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableHeaderBackgroundColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableHeaderBackgroundColor', []);
+
+        return parent::getResultDatatableHeaderBackgroundColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableHeaderBackgroundColor($resultDatatableHeaderBackgroundColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableHeaderBackgroundColor', [$resultDatatableHeaderBackgroundColor]);
+
+        return parent::setResultDatatableHeaderBackgroundColor($resultDatatableHeaderBackgroundColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableHeaderTextColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableHeaderTextColor', []);
+
+        return parent::getResultDatatableHeaderTextColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableHeaderTextColor($resultDatatableHeaderTextColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableHeaderTextColor', [$resultDatatableHeaderTextColor]);
+
+        return parent::setResultDatatableHeaderTextColor($resultDatatableHeaderTextColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableRowsBackgroundColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableRowsBackgroundColor', []);
+
+        return parent::getResultDatatableRowsBackgroundColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableRowsBackgroundColor($resultDatatableRowsBackgroundColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableRowsBackgroundColor', [$resultDatatableRowsBackgroundColor]);
+
+        return parent::setResultDatatableRowsBackgroundColor($resultDatatableRowsBackgroundColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableRowsTextColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableRowsTextColor', []);
+
+        return parent::getResultDatatableRowsTextColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableRowsTextColor($resultDatatableRowsTextColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableRowsTextColor', [$resultDatatableRowsTextColor]);
+
+        return parent::setResultDatatableRowsTextColor($resultDatatableRowsTextColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableSortedColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableSortedColor', []);
+
+        return parent::getResultDatatableSortedColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableSortedColor($resultDatatableSortedColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableSortedColor', [$resultDatatableSortedColor]);
+
+        return parent::setResultDatatableSortedColor($resultDatatableSortedColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableSortedActiveColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableSortedActiveColor', []);
+
+        return parent::getResultDatatableSortedActiveColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableSortedActiveColor($resultDatatableSortedActiveColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableSortedActiveColor', [$resultDatatableSortedActiveColor]);
+
+        return parent::setResultDatatableSortedActiveColor($resultDatatableSortedActiveColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableLinkColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableLinkColor', []);
+
+        return parent::getResultDatatableLinkColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableLinkColor($resultDatatableLinkColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableLinkColor', [$resultDatatableLinkColor]);
+
+        return parent::setResultDatatableLinkColor($resultDatatableLinkColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableLinkHoverColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableLinkHoverColor', []);
+
+        return parent::getResultDatatableLinkHoverColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableLinkHoverColor($resultDatatableLinkHoverColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableLinkHoverColor', [$resultDatatableLinkHoverColor]);
+
+        return parent::setResultDatatableLinkHoverColor($resultDatatableLinkHoverColor);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getResultDatatableRowsSelectedColor()
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'getResultDatatableRowsSelectedColor', []);
+
+        return parent::getResultDatatableRowsSelectedColor();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setResultDatatableRowsSelectedColor($resultDatatableRowsSelectedColor)
+    {
+
+        $this->__initializer__ && $this->__initializer__->__invoke($this, 'setResultDatatableRowsSelectedColor', [$resultDatatableRowsSelectedColor]);
+
+        return parent::setResultDatatableRowsSelectedColor($resultDatatableRowsSelectedColor);
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/server/src/Action/InstanceAction.php b/server/src/Action/InstanceAction.php
index 74fa0804..c32fc021 100644
--- a/server/src/Action/InstanceAction.php
+++ b/server/src/Action/InstanceAction.php
@@ -105,6 +105,17 @@ final class InstanceAction extends AbstractAction
                 'result_header_btn_color',
                 'result_header_btn_hover_color',
                 'result_header_btn_text_color',
+                'result_datatable_bordered',
+                'result_datatable_border_color',
+                'result_datatable_header_background_color',
+                'result_datatable_header_text_color',
+                'result_datatable_rows_background_color',
+                'result_datatable_rows_text_color',
+                'result_datatable_sorted_color',
+                'result_datatable_sorted_active_color',
+                'result_datatable_link_color',
+                'result_datatable_link_hover_color',
+                'result_datatable_rows_selected_color',
                 'samp_enabled',
                 'back_to_portal',
                 'user_menu_enabled',
@@ -191,6 +202,17 @@ final class InstanceAction extends AbstractAction
         $instance->setResultHeaderBtnColor($parsedBody['result_header_btn_color']);
         $instance->setResultHeaderBtnHoverColor($parsedBody['result_header_btn_hover_color']);
         $instance->setResultHeaderBtnTextColor($parsedBody['result_header_btn_text_color']);
+        $instance->setResultDatatableBordered($parsedBody['result_datatable_bordered']);
+        $instance->setResultDatatableBorderColor($parsedBody['result_datatable_border_color']);
+        $instance->setResultDatatableHeaderBackgroundColor($parsedBody['result_datatable_header_background_color']);
+        $instance->setResultDatatableHeaderTextColor($parsedBody['result_datatable_header_text_color']);
+        $instance->setResultDatatableRowsBackgroundColor($parsedBody['result_datatable_rows_background_color']);
+        $instance->setResultDatatableRowsTextColor($parsedBody['result_datatable_rows_text_color']);
+        $instance->setResultDatatableSortedColor($parsedBody['result_datatable_sorted_color']);
+        $instance->setResultDatatableSortedActiveColor($parsedBody['result_datatable_sorted_active_color']);
+        $instance->setResultDatatableLinkColor($parsedBody['result_datatable_link_color']);
+        $instance->setResultDatatableLinkHoverColor($parsedBody['result_datatable_link_hover_color']);
+        $instance->setResultDatatableRowsSelectedColor($parsedBody['result_datatable_rows_selected_color']);
         $instance->setSampEnabled($parsedBody['samp_enabled']);
         $instance->setUserMenuEnabled($parsedBody['user_menu_enabled']);
         $instance->setBackToPortal($parsedBody['back_to_portal']);
diff --git a/server/src/Action/InstanceListAction.php b/server/src/Action/InstanceListAction.php
index fdcd7f3e..64f3842e 100644
--- a/server/src/Action/InstanceListAction.php
+++ b/server/src/Action/InstanceListAction.php
@@ -105,6 +105,17 @@ final class InstanceListAction extends AbstractAction
                 'result_header_btn_color',
                 'result_header_btn_hover_color',
                 'result_header_btn_text_color',
+                'result_datatable_bordered',
+                'result_datatable_border_color',
+                'result_datatable_header_background_color',
+                'result_datatable_header_text_color',
+                'result_datatable_rows_background_color',
+                'result_datatable_rows_text_color',
+                'result_datatable_sorted_color',
+                'result_datatable_sorted_active_color',
+                'result_datatable_link_color',
+                'result_datatable_link_hover_color',
+                'result_datatable_rows_selected_color',
                 'samp_enabled',
                 'back_to_portal',
                 'user_menu_enabled',
@@ -185,6 +196,17 @@ final class InstanceListAction extends AbstractAction
         $instance->setResultHeaderBtnColor($parsedBody['result_header_btn_color']);
         $instance->setResultHeaderBtnHoverColor($parsedBody['result_header_btn_hover_color']);
         $instance->setResultHeaderBtnTextColor($parsedBody['result_header_btn_text_color']);
+        $instance->setResultDatatableBordered($parsedBody['result_datatable_bordered']);
+        $instance->setResultDatatableBorderColor($parsedBody['result_datatable_border_color']);
+        $instance->setResultDatatableHeaderBackgroundColor($parsedBody['result_datatable_header_background_color']);
+        $instance->setResultDatatableHeaderTextColor($parsedBody['result_datatable_header_text_color']);
+        $instance->setResultDatatableRowsBackgroundColor($parsedBody['result_datatable_rows_background_color']);
+        $instance->setResultDatatableRowsTextColor($parsedBody['result_datatable_rows_text_color']);
+        $instance->setResultDatatableSortedColor($parsedBody['result_datatable_sorted_color']);
+        $instance->setResultDatatableSortedActiveColor($parsedBody['result_datatable_sorted_active_color']);
+        $instance->setResultDatatableLinkColor($parsedBody['result_datatable_link_color']);
+        $instance->setResultDatatableLinkHoverColor($parsedBody['result_datatable_link_hover_color']);
+        $instance->setResultDatatableRowsSelectedColor($parsedBody['result_datatable_rows_selected_color']);
         $instance->setSampEnabled($parsedBody['samp_enabled']);
         $instance->setBackToPortal($parsedBody['back_to_portal']);
         $instance->setUserMenuEnabled($parsedBody['user_menu_enabled']);
diff --git a/server/src/Entity/Instance.php b/server/src/Entity/Instance.php
index 8bdee7d7..9678463e 100644
--- a/server/src/Entity/Instance.php
+++ b/server/src/Entity/Instance.php
@@ -322,6 +322,97 @@ class Instance implements \JsonSerializable
      */
     protected $resultHeaderBtnTextColor;
 
+    /**
+     * @var bool
+     *
+     * @Column(type="boolean", name="result_datatable_bordered", nullable=false, options={"default" : true})
+     */
+    protected $resultDatatableBordered;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_border_color", nullable=false, options={
+     *     "default" : "#DEE2E6"
+     * })
+     */
+    protected $resultDatatableBorderColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_header_background_color", nullable=false, options={
+     *     "default" : "#FFFFFF"
+     * })
+     */
+    protected $resultDatatableHeaderBackgroundColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_header_text_color", nullable=false, options={
+     *     "default" : "#000000"
+     * })
+     */
+    protected $resultDatatableHeaderTextColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_rows_background_color", nullable=false, options={
+     *     "default" : "#FFFFFF"
+     * })
+     */
+    protected $resultDatatableRowsBackgroundColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_rows_text_color", nullable=false, options={"default" : "#000000"})
+     */
+    protected $resultDatatableRowsTextColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_sorted_color", nullable=false, options={"default" : "#C5C5C5"})
+     */
+    protected $resultDatatableSortedColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_sorted_active_color", nullable=false, options={"
+     *     default" : "#000000"
+     * })
+     */
+    protected $resultDatatableSortedActiveColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_link_color", nullable=false, options={"default" : "#007BFF"})
+     */
+    protected $resultDatatableLinkColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_link_hover_color", nullable=false, options={"
+     *     default" : "#0056B3"
+     * })
+     */
+    protected $resultDatatableLinkHoverColor;
+
+    /**
+     * @var string
+     *
+     * @Column(type="string", name="result_datatable_rows_selected_color", nullable=false, options={"
+     *     default" : "#7AC29A"
+     * })
+     */
+    protected $resultDatatableRowsSelectedColor;
+
     /**
      * @var bool
      *
@@ -821,6 +912,116 @@ class Instance implements \JsonSerializable
         $this->resultHeaderBtnTextColor = $resultHeaderBtnTextColor;
     }
 
+    public function getResultDatatableBordered()
+    {
+        return $this->resultDatatableBordered;
+    }
+
+    public function setResultDatatableBordered($resultDatatableBordered)
+    {
+        $this->resultDatatableBordered = $resultDatatableBordered;
+    }
+
+    public function getResultDatatableBorderColor()
+    {
+        return $this->resultDatatableBorderColor;
+    }
+
+    public function setResultDatatableBorderColor($resultDatatableBorderColor)
+    {
+        $this->resultDatatableBorderColor = $resultDatatableBorderColor;
+    }
+
+    public function getResultDatatableHeaderBackgroundColor()
+    {
+        return $this->resultDatatableHeaderBackgroundColor;
+    }
+
+    public function setResultDatatableHeaderBackgroundColor($resultDatatableHeaderBackgroundColor)
+    {
+        $this->resultDatatableHeaderBackgroundColor = $resultDatatableHeaderBackgroundColor;
+    }
+
+    public function getResultDatatableHeaderTextColor()
+    {
+        return $this->resultDatatableHeaderTextColor;
+    }
+
+    public function setResultDatatableHeaderTextColor($resultDatatableHeaderTextColor)
+    {
+        $this->resultDatatableHeaderTextColor = $resultDatatableHeaderTextColor;
+    }
+
+    public function getResultDatatableRowsBackgroundColor()
+    {
+        return $this->resultDatatableRowsBackgroundColor;
+    }
+
+    public function setResultDatatableRowsBackgroundColor($resultDatatableRowsBackgroundColor)
+    {
+        $this->resultDatatableRowsBackgroundColor = $resultDatatableRowsBackgroundColor;
+    }
+
+    public function getResultDatatableRowsTextColor()
+    {
+        return $this->resultDatatableRowsTextColor;
+    }
+
+    public function setResultDatatableRowsTextColor($resultDatatableRowsTextColor)
+    {
+        $this->resultDatatableRowsTextColor = $resultDatatableRowsTextColor;
+    }
+
+    public function getResultDatatableSortedColor()
+    {
+        return $this->resultDatatableSortedColor;
+    }
+
+    public function setResultDatatableSortedColor($resultDatatableSortedColor)
+    {
+        $this->resultDatatableSortedColor = $resultDatatableSortedColor;
+    }
+
+    public function getResultDatatableSortedActiveColor()
+    {
+        return $this->resultDatatableSortedActiveColor;
+    }
+
+    public function setResultDatatableSortedActiveColor($resultDatatableSortedActiveColor)
+    {
+        $this->resultDatatableSortedActiveColor = $resultDatatableSortedActiveColor;
+    }
+
+    public function getResultDatatableLinkColor()
+    {
+        return $this->resultDatatableLinkColor;
+    }
+
+    public function setResultDatatableLinkColor($resultDatatableLinkColor)
+    {
+        $this->resultDatatableLinkColor = $resultDatatableLinkColor;
+    }
+
+    public function getResultDatatableLinkHoverColor()
+    {
+        return $this->resultDatatableLinkHoverColor;
+    }
+
+    public function setResultDatatableLinkHoverColor($resultDatatableLinkHoverColor)
+    {
+        $this->resultDatatableLinkHoverColor = $resultDatatableLinkHoverColor;
+    }
+
+    public function getResultDatatableRowsSelectedColor()
+    {
+        return $this->resultDatatableRowsSelectedColor;
+    }
+
+    public function setResultDatatableRowsSelectedColor($resultDatatableRowsSelectedColor)
+    {
+        $this->resultDatatableRowsSelectedColor = $resultDatatableRowsSelectedColor;
+    }
+
     public function getSampEnabled()
     {
         return $this->sampEnabled;
@@ -980,6 +1181,17 @@ class Instance implements \JsonSerializable
             'result_header_btn_color' => $this->getResultHeaderBtnColor(),
             'result_header_btn_hover_color' => $this->getResultHeaderBtnHoverColor(),
             'result_header_btn_text_color' => $this->getResultHeaderBtnTextColor(),
+            'result_datatable_bordered' => $this->getResultDatatableBordered(),
+            'result_datatable_border_color' => $this->getResultDatatableBorderColor(),
+            'result_datatable_header_background_color' => $this->getResultDatatableHeaderBackgroundColor(),
+            'result_datatable_header_text_color' => $this->getResultDatatableHeaderTextColor(),
+            'result_datatable_rows_background_color' => $this->getResultDatatableRowsBackgroundColor(),
+            'result_datatable_rows_text_color' => $this->getResultDatatableRowsTextColor(),
+            'result_datatable_sorted_color' => $this->getResultDatatableSortedColor(),
+            'result_datatable_sorted_active_color' => $this->getResultDatatableSortedActiveColor(),
+            'result_datatable_link_color' => $this->getResultDatatableLinkColor(),
+            'result_datatable_link_hover_color' => $this->getResultDatatableLinkHoverColor(),
+            'result_datatable_rows_selected_color' => $this->getResultDatatableRowsSelectedColor(),
             'samp_enabled' => $this->getSampEnabled(),
             'back_to_portal' => $this->getBackToPortal(),
             'user_menu_enabled' => $this->getUserMenuEnabled(),
diff --git a/server/tests/Action/InstanceActionTest.php b/server/tests/Action/InstanceActionTest.php
index f5e3465d..d5d2f812 100644
--- a/server/tests/Action/InstanceActionTest.php
+++ b/server/tests/Action/InstanceActionTest.php
@@ -119,6 +119,17 @@ final class InstanceActionTest extends TestCase
             'result_header_btn_color' => '#007BFF',
             'result_header_btn_hover_color' => '#0069D9',
             'result_header_btn_text_color' => '#FFFFFF',
+            'result_datatable_bordered' => true,
+            'result_datatable_border_color' => '#DEE2E6',
+            'result_datatable_header_background_color' => '#FFFFFF',
+            'result_datatable_header_text_color' => '#000000',
+            'result_datatable_rows_background_color' => '#FFFFFF',
+            'result_datatable_rows_text_color' => '#000000',
+            'result_datatable_sorted_color' => '#C5C5C5',
+            'result_datatable_sorted_active_color' => '#000000',
+            'result_datatable_link_color' => '#007BFF',
+            'result_datatable_link_hover_color' => '#0056B3',
+            'result_datatable_rows_selected_color' => '#7AC29A',
             'samp_enabled' => true,
             'back_to_portal' => true,
             'user_menu_enabled' => true,
diff --git a/server/tests/Action/InstanceListActionTest.php b/server/tests/Action/InstanceListActionTest.php
index 32eab147..7af0c72b 100644
--- a/server/tests/Action/InstanceListActionTest.php
+++ b/server/tests/Action/InstanceListActionTest.php
@@ -103,8 +103,17 @@ final class InstanceListActionTest extends TestCase
             'result_header_btn_color' => '#007BFF',
             'result_header_btn_hover_color' => '#0069D9',
             'result_header_btn_text_color' => '#FFFFFF',
-            'home_component' => 'WelcomeComponent',
-            'home_component_config' => '{}',
+            'result_datatable_bordered' => true,
+            'result_datatable_border_color' => '#DEE2E6',
+            'result_datatable_header_background_color' => '#FFFFFF',
+            'result_datatable_header_text_color' => '#000000',
+            'result_datatable_rows_background_color' => '#FFFFFF',
+            'result_datatable_rows_text_color' => '#000000',
+            'result_datatable_sorted_color' => '#C5C5C5',
+            'result_datatable_sorted_active_color' => '#000000',
+            'result_datatable_link_color' => '#007BFF',
+            'result_datatable_link_hover_color' => '#0056B3',
+            'result_datatable_rows_selected_color' => '#7AC29A',
             'samp_enabled' => true,
             'back_to_portal' => true,
             'user_menu_enabled' => true,
-- 
GitLab