From 0d0deb40f73a9baed15a55dfe9516e6cc1065961 Mon Sep 17 00:00:00 2001
From: Florent Poittevin <florent.poittevin@unige.ch>
Date: Mon, 28 Oct 2019 11:18:43 +0100
Subject: [PATCH] fix: 838 Fix filter by status in deposit data table

---
 .../deposit-list/deposit-list.routable.ts     |  44 +++++++
 .../shared-data-table.presentational.html     |  82 +++++++++----
 .../shared-data-table.presentational.scss     |  21 +++-
 .../shared-data-table.presentational.ts       |   2 +-
 .../shared/models/data-table-columns.model.ts |   8 +-
 src/assets/i18n/de.json                       | 108 +++---------------
 src/assets/i18n/en.json                       | 104 +++--------------
 src/assets/i18n/fr.json                       | 104 +++--------------
 8 files changed, 171 insertions(+), 302 deletions(-)

diff --git a/src/app/features/deposit/components/routables/deposit-list/deposit-list.routable.ts b/src/app/features/deposit/components/routables/deposit-list/deposit-list.routable.ts
index 4dc4f8975..486b27a3f 100644
--- a/src/app/features/deposit/components/routables/deposit-list/deposit-list.routable.ts
+++ b/src/app/features/deposit/components/routables/deposit-list/deposit-list.routable.ts
@@ -7,6 +7,7 @@ import {
 import {DepositExtended} from "@app/features/deposit/models/deposits-extended.model";
 import {depositActionNameSpace} from "@app/features/deposit/stores/deposit.action";
 import {DepositStateModel} from "@app/features/deposit/stores/deposit.state";
+import {Deposit} from "@app/generated-api/model/deposit.model";
 import {SharedAbstractListRoutable} from "@app/shared/components/routables/shared-abstract-list/shared-abstract-list.routable";
 import {FieldTypeEnum} from "@app/shared/enums/field-type.enum";
 import {LocalStateEnum} from "@app/shared/enums/local-state.enum";
@@ -79,6 +80,49 @@ export class DepositListRoutable extends SharedAbstractListRoutable<DepositExten
         order: OrderEnum.none,
         isFilterable: true,
         isSortable: true,
+        translate: true,
+        filterEnum: [
+          {
+            key: Deposit.StatusEnum.INPROGRESS,
+            value: TRANSLATE("IN_PROGRESS"),
+          },
+          {
+            key: Deposit.StatusEnum.INVALIDATION,
+            value: TRANSLATE("IN_VALIDATION"),
+          },
+          {
+            key: Deposit.StatusEnum.REJECTED,
+            value: TRANSLATE("REJECTED"),
+          },
+          {
+            key: Deposit.StatusEnum.INERROR,
+            value: TRANSLATE("IN_ERROR"),
+          },
+          {
+            key: Deposit.StatusEnum.PAUSED,
+            value: TRANSLATE("PAUSED"),
+          },
+          {
+            key: Deposit.StatusEnum.CHECKED,
+            value: TRANSLATE("CHECKED"),
+          },
+          {
+            key: Deposit.StatusEnum.REJECTED,
+            value: TRANSLATE("REJECTED"),
+          },
+          {
+            key: Deposit.StatusEnum.APPROVED,
+            value: TRANSLATE("APPROVED"),
+          },
+          {
+            key: Deposit.StatusEnum.SUBMITTED,
+            value: TRANSLATE("SUBMITTED"),
+          },
+          {
+            key: Deposit.StatusEnum.COMPLETED,
+            value: TRANSLATE("COMPLETED"),
+          },
+        ],
       },
     ];
   }
diff --git a/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.html b/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.html
index 77368a4f8..1cd06e97c 100644
--- a/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.html
+++ b/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.html
@@ -34,29 +34,58 @@
             <div *ngSwitchCase="fieldTypeString"
                  class="filter-text"
             >
-              <!--            <mat-form-field style="width: 100%" [floatLabel]="'never'">-->
-              <!--              <input #filter matInput (keyup)="onValueChange(col, $event.target.value)" [value]="getValue(col.field)">-->
-              <!--              <button mat-button *ngIf="filter.value" matSuffix mat-icon-button aria-label="Clear" (click)="filter.value='';onValueChange(col, filter.value)">-->
-              <!--                <fa-icon matSuffix icon="times"></fa-icon>-->
-              <!--              </button>-->
-              <!--            </mat-form-field>-->
-
-              <input type="text "
-                     #filter
-                     (keyup)="onValueChange(col, $event.target.value)"
-                     [value]="getValue(col.field)"
-              >
-              <button mat-button
-                      *ngIf="filter.value"
-                      matSuffix
-                      mat-icon-button
-                      aria-label="Clear"
-                      (click)="filter.value='';onValueChange(col, filter.value)"
+              <ng-template [ngIf]="col.filterEnum"
+                           [ngIfElse]="inputFilter"
               >
-                <fa-icon matSuffix
-                         icon="times"
-                ></fa-icon>
-              </button>
+                <mat-select #select
+                            [class.no-value]="!select.value"
+                            (selectionChange)="onValueChange(col, $event.value)"
+                >
+                  <mat-option>{{'table.filter.all' | translate}}</mat-option>
+                  <mat-option *ngFor="let enum of col.filterEnum"
+                              [value]="enum.key"
+                  >
+                    <ng-template [ngIf]="col.translate"
+                                 [ngIfElse]="noTranslate"
+                    >
+                      {{enum.value | translate}}
+                    </ng-template>
+                    <ng-template #noTranslate>
+                      {{enum.value}}
+                    </ng-template>
+                  </mat-option>
+                </mat-select>
+                <button mat-button
+                        *ngIf="select.value"
+                        matSuffix
+                        mat-icon-button
+                        aria-label="Clear"
+                        (click)="select.value='';onValueChange(col, select.value)"
+                >
+                  <fa-icon matSuffix
+                           icon="times"
+                  ></fa-icon>
+                </button>
+              </ng-template>
+
+              <ng-template #inputFilter>
+                <input type="text"
+                       #filter
+                       (keyup)="onValueChange(col, $event.target.value)"
+                       [value]="getValue(col.field)"
+                >
+                <button mat-button
+                        *ngIf="filter.value"
+                        matSuffix
+                        mat-icon-button
+                        aria-label="Clear"
+                        (click)="filter.value='';onValueChange(col, filter.value)"
+                >
+                  <fa-icon matSuffix
+                           icon="times"
+                  ></fa-icon>
+                </button>
+              </ng-template>
             </div>
           </ng-container>
         </th>
@@ -72,7 +101,14 @@
       >
         <td *ngFor="let col of columns">
           <span class="ui-column-title">{{col.header | translate}}</span>
-          {{getCellData(rowData, col)}}
+          <ng-template [ngIf]="col.translate"
+                       [ngIfElse]="noTranslate"
+          >
+            {{getCellData(rowData, col) | translate}}
+          </ng-template>
+          <ng-template #noTranslate>
+            {{getCellData(rowData, col)}}
+          </ng-template>
         </td>
       </tr>
     </ng-template>
diff --git a/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.scss b/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.scss
index c91fce9b6..2e41ad075 100644
--- a/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.scss
+++ b/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.scss
@@ -117,13 +117,30 @@ $inputGroupTextColor: #444444;
     .filter-text {
       position: relative;
 
-      input {
+      input, mat-select {
         background-color: $primary-color-lighter !important;
         border: 0;
         border-radius: 5px;
         padding: 6px 30px 6px 10px;
         width: 100%;
-        color: white;
+        color: $white;
+        height: 30px;
+      }
+
+      mat-select {
+        .mat-select-value {
+          color: $white;
+          font-weight: initial;
+          text-align: left;
+        }
+
+        .mat-select-arrow {
+          color: $white;
+        }
+
+        &.no-value {
+          padding-right: 6px;
+        }
       }
 
       button {
diff --git a/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.ts b/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.ts
index 0f7b3d64d..7ba9db52a 100644
--- a/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.ts
+++ b/src/app/shared/components/presentationals/shared-data-table/shared-data-table.presentational.ts
@@ -176,7 +176,7 @@ export class SharedDataTablePresentational<T> extends SharedAbstractPresentation
 
   onValueChange(col: DataTableColumns, value: string): void {
     let queryParameters = ObjectUtil.clone(this.queryParameters);
-    if (isEmptyString(value)) {
+    if (isEmptyString(value) || isNullOrUndefined(value)) {
       queryParameters.search.searchItems.delete(col.field);
     } else {
       MapUtil.addOrUpdate(queryParameters.search.searchItems, col.field, value);
diff --git a/src/app/shared/models/data-table-columns.model.ts b/src/app/shared/models/data-table-columns.model.ts
index 7c78f0dc0..ad9fa0bf5 100644
--- a/src/app/shared/models/data-table-columns.model.ts
+++ b/src/app/shared/models/data-table-columns.model.ts
@@ -1,11 +1,17 @@
 import {FieldTypeEnum} from "@app/shared/enums/field-type.enum";
-import {OrderEnum} from "solidify-frontend";
+import {
+  KeyValue,
+  OrderEnum,
+} from "solidify-frontend";
 
 export interface DataTableColumns<T = any> {
   field: keyof T & string;
   header: string;
   type?: FieldTypeEnum;
   order: OrderEnum;
+  filterEnum?: KeyValue[];
+  isMultipleFilterEnum?: boolean;
+  translate?: boolean;
   isSortable?: boolean;
   isFilterable?: boolean;
 }
diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json
index da25a9077..745742555 100644
--- a/src/assets/i18n/de.json
+++ b/src/assets/i18n/de.json
@@ -1,5 +1,14 @@
 {
+  "APPROVED": "Approved",
+  "CHECKED": "Checked",
+  "COMPLETED": "Completed",
   "Description is invalid": "Description is invalid",
+  "IN_ERROR": "In error",
+  "IN_PROGRESS": "In progress",
+  "IN_VALIDATION": "In validation",
+  "PAUSED": "Paused",
+  "REJECTED": "Rejected",
+  "SUBMITTED": "Submitted",
   "URL is invalid": "URL is invalid",
   "access": {
     "organizationalUnitNotFound": "Unable to get data",
@@ -477,16 +486,7 @@
     "navigation": {
       "button": {
         "backToDetail": "Leave edit mode",
-        "backToList": "app.navigation.button.backToList"
-      }
-    },
-    "person": {
-      "notification": {
-        "resource": {
-          "create": "Person created with success",
-          "delete": "Person deleted with success",
-          "update": "Person updated with success"
-        }
+        "backToList": "Back to list"
       }
     },
     "status": {
@@ -526,13 +526,6 @@
         "close": "Close",
         "submit": "Validate"
       },
-      "notification": {
-        "resource": {
-          "create": "User created with success",
-          "delete": "User deleted with success",
-          "update": "User updated with success"
-        }
-      },
       "personal": {
         "form": {
           "firstName": "First name",
@@ -855,16 +848,7 @@
     "button": {
       "goToArchivalBrowsing": "Go to archive browsing"
     },
-    "or": "or",
-    "orgunit": {
-      "notification": {
-        "resource": {
-          "create": "Organizational Unit created with success",
-          "delete": "Organizational Unit deleted with success",
-          "update": "Organizational Unit updated with success"
-        }
-      }
-    }
+    "or": "or"
   },
   "homePage": {
     "archive": {
@@ -910,7 +894,6 @@
     "delete": "Delete",
     "description": "Description",
     "edit": "Edit",
-    "isEmpty": "Is Empty",
     "name": "Name",
     "new": "Create new organizational unit",
     "notification": {
@@ -920,7 +903,6 @@
         "update": "Organizational Unit updated with success"
       }
     },
-    "open": "Open",
     "openingDate": "Opening Date",
     "refresh": "Refresh",
     "submit": "Submit",
@@ -937,42 +919,6 @@
   "required": "This field is required",
   "search": "Search",
   "shared": {
-    "fundingAgency": {
-      "notification": {
-        "resource": {
-          "create": "Funding Agency created with success",
-          "delete": "Funding Agency deleted with success",
-          "update": "Funding Agency updated with success"
-        }
-      }
-    },
-    "institution": {
-      "notification": {
-        "resource": {
-          "create": "shared.institution.notification.resource.create",
-          "delete": "shared.institution.notification.resource.delete",
-          "update": "shared.institution.notification.resource.update"
-        }
-      }
-    },
-    "language": {
-      "notification": {
-        "resource": {
-          "create": "Language created with success",
-          "delete": "Language deleted with success",
-          "update": "Language updated with success"
-        }
-      }
-    },
-    "license": {
-      "notification": {
-        "resource": {
-          "create": "License created with success",
-          "delete": "License deleted with success",
-          "update": "License updated with success"
-        }
-      }
-    },
     "multiSelectDefaultValue": {
       "defaultValue": "Default value"
     },
@@ -1005,36 +951,12 @@
       "tooltip": {
         "delete": "Delete"
       }
-    },
-    "preservationPolicy": {
-      "notification": {
-        "resource": {
-          "create": "Preservation Policy created with success",
-          "delete": "Preservation Policy deleted with success",
-          "update": "Preservation Policy updated with success"
-        }
-      }
-    },
-    "role": {
-      "notification": {
-        "resource": {
-          "create": "Role created with success",
-          "delete": "Role deleted with success",
-          "update": "Role updated with success"
-        }
-      }
-    },
-    "submissionPolicy": {
-      "notification": {
-        "resource": {
-          "create": "Submission Policy created with success",
-          "delete": "Submission Policy deleted with success",
-          "update": "Submission Policy updated with success"
-        }
-      }
     }
   },
   "table": {
+    "filter": {
+      "all": "All"
+    },
     "nodata": "No data has been found",
     "paginator": {
       "firstPage": "First page",
@@ -1056,4 +978,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index 7fa355f97..745742555 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -1,5 +1,14 @@
 {
+  "APPROVED": "Approved",
+  "CHECKED": "Checked",
+  "COMPLETED": "Completed",
   "Description is invalid": "Description is invalid",
+  "IN_ERROR": "In error",
+  "IN_PROGRESS": "In progress",
+  "IN_VALIDATION": "In validation",
+  "PAUSED": "Paused",
+  "REJECTED": "Rejected",
+  "SUBMITTED": "Submitted",
   "URL is invalid": "URL is invalid",
   "access": {
     "organizationalUnitNotFound": "Unable to get data",
@@ -480,15 +489,6 @@
         "backToList": "Back to list"
       }
     },
-    "person": {
-      "notification": {
-        "resource": {
-          "create": "Person created with success",
-          "delete": "Person deleted with success",
-          "update": "Person updated with success"
-        }
-      }
-    },
     "status": {
       "backToOnline": "You are back to online",
       "newVersionAvailable": "A new version of the application is available",
@@ -526,13 +526,6 @@
         "close": "Close",
         "submit": "Validate"
       },
-      "notification": {
-        "resource": {
-          "create": "User created with success",
-          "delete": "User deleted with success",
-          "update": "User updated with success"
-        }
-      },
       "personal": {
         "form": {
           "firstName": "First name",
@@ -855,16 +848,7 @@
     "button": {
       "goToArchivalBrowsing": "Go to archive browsing"
     },
-    "or": "or",
-    "orgunit": {
-      "notification": {
-        "resource": {
-          "create": "Organizational Unit created with success",
-          "delete": "Organizational Unit deleted with success",
-          "update": "Organizational Unit updated with success"
-        }
-      }
-    }
+    "or": "or"
   },
   "homePage": {
     "archive": {
@@ -910,7 +894,6 @@
     "delete": "Delete",
     "description": "Description",
     "edit": "Edit",
-    "isEmpty": "Is Empty",
     "name": "Name",
     "new": "Create new organizational unit",
     "notification": {
@@ -920,7 +903,6 @@
         "update": "Organizational Unit updated with success"
       }
     },
-    "open": "Open",
     "openingDate": "Opening Date",
     "refresh": "Refresh",
     "submit": "Submit",
@@ -937,42 +919,6 @@
   "required": "This field is required",
   "search": "Search",
   "shared": {
-    "fundingAgency": {
-      "notification": {
-        "resource": {
-          "create": "Funding Agency created with success",
-          "delete": "Funding Agency deleted with success",
-          "update": "Funding Agency updated with success"
-        }
-      }
-    },
-    "institution": {
-      "notification": {
-        "resource": {
-          "create": "shared.institution.notification.resource.create",
-          "delete": "shared.institution.notification.resource.delete",
-          "update": "shared.institution.notification.resource.update"
-        }
-      }
-    },
-    "language": {
-      "notification": {
-        "resource": {
-          "create": "Language created with success",
-          "delete": "Language deleted with success",
-          "update": "Language updated with success"
-        }
-      }
-    },
-    "license": {
-      "notification": {
-        "resource": {
-          "create": "License created with success",
-          "delete": "License deleted with success",
-          "update": "License updated with success"
-        }
-      }
-    },
     "multiSelectDefaultValue": {
       "defaultValue": "Default value"
     },
@@ -1005,36 +951,12 @@
       "tooltip": {
         "delete": "Delete"
       }
-    },
-    "preservationPolicy": {
-      "notification": {
-        "resource": {
-          "create": "Preservation Policy created with success",
-          "delete": "Preservation Policy deleted with success",
-          "update": "Preservation Policy updated with success"
-        }
-      }
-    },
-    "role": {
-      "notification": {
-        "resource": {
-          "create": "Role created with success",
-          "delete": "Role deleted with success",
-          "update": "Role updated with success"
-        }
-      }
-    },
-    "submissionPolicy": {
-      "notification": {
-        "resource": {
-          "create": "Submission Policy created with success",
-          "delete": "Submission Policy deleted with success",
-          "update": "Submission Policy updated with success"
-        }
-      }
     }
   },
   "table": {
+    "filter": {
+      "all": "All"
+    },
     "nodata": "No data has been found",
     "paginator": {
       "firstPage": "First page",
diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json
index 9a801c8a4..47230107c 100644
--- a/src/assets/i18n/fr.json
+++ b/src/assets/i18n/fr.json
@@ -1,5 +1,14 @@
 {
+  "APPROVED": "Approuvé",
+  "CHECKED": "Vérifié",
+  "COMPLETED": "Complété",
   "Description is invalid": "La description est invalide",
+  "IN_ERROR": "En erreur",
+  "IN_PROGRESS": "En cours",
+  "IN_VALIDATION": "En validation",
+  "PAUSED": "En pause",
+  "REJECTED": "Rejeté",
+  "SUBMITTED": "Soumis",
   "URL is invalid": "URL invalide",
   "access": {
     "organizationalUnitNotFound": "Impossible d'obtenir les données",
@@ -480,15 +489,6 @@
         "backToList": "Retour à la liste"
       }
     },
-    "person": {
-      "notification": {
-        "resource": {
-          "create": "Personne créée avec succès",
-          "delete": "Personne supprimée avec succès",
-          "update": "Personne mise à jour avec succès"
-        }
-      }
-    },
     "status": {
       "backToOnline": "Vous êtes de nouveau en ligne",
       "newVersionAvailable": "Une nouvelle version de l'application est disponible",
@@ -526,13 +526,6 @@
         "close": "Fermer",
         "submit": "Valider"
       },
-      "notification": {
-        "resource": {
-          "create": "Utilisateur créé avec succès",
-          "delete": "Utilisateur supprimé avec succès",
-          "update": "Utilisateur mise à jour avec succès"
-        }
-      },
       "personal": {
         "form": {
           "firstName": "Prénom",
@@ -855,16 +848,7 @@
     "button": {
       "goToArchivalBrowsing": "Navigation dans les archives"
     },
-    "or": "ou",
-    "orgunit": {
-      "notification": {
-        "resource": {
-          "create": "Unité Organisationnelle créée avec succès",
-          "delete": "Unité Organisationnelle supprimée avec succès",
-          "update": "Unité Organisationnelle mise à jour avec succès"
-        }
-      }
-    }
+    "or": "ou"
   },
   "homePage": {
     "archive": {
@@ -910,7 +894,6 @@
     "delete": "Supprimer",
     "description": "Description",
     "edit": "Modifier",
-    "isEmpty": "Est vide",
     "name": "Nom",
     "new": "Créer nouvelle unité organisationnelle",
     "notification": {
@@ -920,7 +903,6 @@
         "update": "Unité Organisationnelle mise à jour avec succès"
       }
     },
-    "open": "Ouvert",
     "openingDate": "Date d'ouverture",
     "refresh": "Rafraichir",
     "submit": "Envoyer",
@@ -937,42 +919,6 @@
   "required": "Ce champ est requis",
   "search": "Recherche",
   "shared": {
-    "fundingAgency": {
-      "notification": {
-        "resource": {
-          "create": "Organisme de financement créée avec succès",
-          "delete": "Organisme de financement supprimée avec succès",
-          "update": "Organisme de financement mise à jour avec succès"
-        }
-      }
-    },
-    "institution": {
-      "notification": {
-        "resource": {
-          "create": "shared.institution.notification.resource.create",
-          "delete": "shared.institution.notification.resource.delete",
-          "update": "shared.institution.notification.resource.update"
-        }
-      }
-    },
-    "language": {
-      "notification": {
-        "resource": {
-          "create": "Language créé avec succès",
-          "delete": "Language supprimé avec succès",
-          "update": "Language mis à jour avec succès"
-        }
-      }
-    },
-    "license": {
-      "notification": {
-        "resource": {
-          "create": "Licence créée avec succès",
-          "delete": "Licence supprimée avec succès",
-          "update": "Licence mise à jour avec succès"
-        }
-      }
-    },
     "multiSelectDefaultValue": {
       "defaultValue": "Valeur par défaut"
     },
@@ -1005,36 +951,12 @@
       "tooltip": {
         "delete": "Supprimer"
       }
-    },
-    "preservationPolicy": {
-      "notification": {
-        "resource": {
-          "create": "Politique de préservation créée avec succès",
-          "delete": "Politique de préservation supprimée avec succès",
-          "update": "Politique de préservation mise à jour avec succès"
-        }
-      }
-    },
-    "role": {
-      "notification": {
-        "resource": {
-          "create": "Personne créé avec succès",
-          "delete": "Personne supprimé avec succès",
-          "update": "Personne mis à jour avec succès"
-        }
-      }
-    },
-    "submissionPolicy": {
-      "notification": {
-        "resource": {
-          "create": "Politique de soumission créée avec succès",
-          "delete": "Politique de soumission supprimée avec succès",
-          "update": "Politique de soumission mise à jour avec succès"
-        }
-      }
     }
   },
   "table": {
+    "filter": {
+      "all": "Tous"
+    },
     "nodata": "Aucune donnée n'a été trouvé",
     "paginator": {
       "firstPage": "Première page",
-- 
GitLab