From a3b53b10624849b43bf801cb7ae1cace9dc666f9 Mon Sep 17 00:00:00 2001
From: "Alicia.DeDiosFuente" <alicia.dediosfuente@unige.ch>
Date: Tue, 10 Sep 2019 17:56:43 +0200
Subject: [PATCH] fix: check all validation to enabled submit button in deposit
 form

---
 .../deposit-form.presentational.ts            |  4 +++
 .../deposit-detail.routable.html              | 13 +++++----
 .../deposit-detail/deposit-detail.routable.ts |  5 ++++
 .../deposit-edit/deposit-edit.routable.html   |  3 +-
 .../deposit-edit/deposit-edit.routable.ts     |  5 ++++
 .../deposit/models/deposit-data-file.model.ts | 15 ++++++++--
 .../shared-abstract-form.presentational.ts    |  2 ++
 .../shared-data-table.presentational.scss     | 15 ++++++----
 .../shared/pipes/all-data-file-ready.pipe.ts  | 29 +++++++++++++++++++
 src/app/shared/shared.module.ts               |  3 +-
 src/sass/abstracts/_mixins.scss               |  6 ++++
 11 files changed, 86 insertions(+), 14 deletions(-)
 create mode 100644 src/app/shared/pipes/all-data-file-ready.pipe.ts

diff --git a/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts b/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts
index 3bb731411..ea069a0c9 100644
--- a/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts
+++ b/src/app/features/deposit/components/presentationals/deposit-form/deposit-form.presentational.ts
@@ -45,6 +45,9 @@ export class DepositFormPresentational extends SharedAbstractFormPresentational<
 
   accessEnumValues: string[] = [...Object.values(AccessEnum)];
 
+  @Input()
+  isReady: boolean = false;
+
   @Input()
   languages: Language[];
 
@@ -126,6 +129,7 @@ export class DepositFormPresentational extends SharedAbstractFormPresentational<
       [this.formDefinition.preservationPolicyId]: [deposit.preservationPolicyId],
       [this.formDefinition.authors]: [_.map(this.selectedPersons, LocalModelAttributeEnum.resId), [Validators.required, SolidifyValidator]],
     });
+    this.isValidWhenDisable = this.form.valid;
   }
 
   protected treatmentBeforeSubmit(deposit: DepositExtended): DepositExtended {
diff --git a/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.html b/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.html
index 1af7256e5..798aa0783 100644
--- a/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.html
+++ b/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.html
@@ -16,9 +16,9 @@
   >
     {{KEY_DELETE_BUTTON | translate}}
   </button>
-  <button *ngIf="((currentObs| async)?.status === statusEnum.INPROGRESS ||
-                 (currentObs| async)?.status === statusEnum.INERROR)
-                 && (listDataFileObs | async) | isNonEmptyArray"
+  <button *ngIf="(currentObs| async)?.status === statusEnum.INPROGRESS
+                 && formPresentational?.isValidWhenDisable
+                 && (listDataFileObs | async)  | allDataFileReady"
           mat-flat-button
           color="primary"
           [disabled]="!(currentObs| async)"
@@ -37,10 +37,12 @@
 
   <mat-tab-group mat-align-tabs="center"
                  animationDuration="0ms"
+                 [selectedIndex]="1"
   >
     <mat-tab [label]="'deposit.tab.details' | translate">
       <div class="tab-content">
-        <dlcm-deposit-form *ngIf="(currentObs| async) != null"
+        <dlcm-deposit-form #formPresentational
+                           *ngIf="(currentObs | async) && !(isLoadingObs | async) && !(isLoadingPersonObs | async)"
                            [model]="currentObs| async"
                            [languages]="languagesObs | async"
                            [licenses]="licensesObs | async"
@@ -50,7 +52,8 @@
                            [listPersons]="listPersonObs | async"
                            [selectedPersons]="selectedPersonObs | async"
                            [readonly]="true"
-        ></dlcm-deposit-form>
+        >
+        </dlcm-deposit-form>
       </div>
     </mat-tab>
     <mat-tab [label]="'deposit.tab.datafiles' | translate">
diff --git a/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts b/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts
index 73579bfe6..4701c717f 100644
--- a/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts
+++ b/src/app/features/deposit/components/routables/deposit-detail/deposit-detail.routable.ts
@@ -2,6 +2,7 @@ import {
   ChangeDetectionStrategy,
   Component,
   OnInit,
+  ViewChild,
 } from "@angular/core";
 import {MatDialog} from "@angular/material";
 import {ActivatedRoute} from "@angular/router";
@@ -27,6 +28,7 @@ import {SharedAbstractDetailRoutable} from "@app/shared/components/routables/sha
 import {LocalStateEnum} from "@app/shared/enums/local-state.enum";
 import {LocalStateModel} from "@app/shared/models/local-state.model";
 import {SharedOrgUnitAction} from "@app/shared/stores/organizational-unit/shared-organizational-unit.action";
+import {DepositFormPresentational} from "@deposit/components/presentationals/deposit-form/deposit-form.presentational";
 import {
   Select,
   Store,
@@ -56,6 +58,9 @@ export class DepositDetailRoutable extends SharedAbstractDetailRoutable<DepositE
   @Select((state: LocalStateModel) => state.deposit.deposit_dataFile.list) listDataFileObs: Observable<DepositDataFile[]>;
   @Select((state: LocalStateModel) => state.deposit.deposit_person.selected) selectedPersonObs: Observable<Person[]>;
 
+  @ViewChild("formPresentational", {static: false})
+  readonly formPresentational: DepositFormPresentational;
+
   readonly KEY_PARAM_NAME: string = "title";
   readonly KEY_DELETE_BUTTON: string = TRANSLATE("deposit.delete");
   readonly KEY_EDIT_BUTTON: string = TRANSLATE("deposit.edit");
diff --git a/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.html b/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.html
index 6135eb8f1..5449234af 100644
--- a/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.html
+++ b/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.html
@@ -6,10 +6,11 @@
   </div>
   <mat-tab-group mat-align-tabs="center"
                  animationDuration="0ms"
+                 [selectedIndex]="1"
   >
     <mat-tab [label]="'deposit.tab.details' | translate">
       <div class="tab-content">
-        <dlcm-deposit-form *ngIf="(currentObs | async) && !(isLoadingObs | async) && !(isLoadingPersonObs | async)"
+        <dlcm-deposit-form #formPresentational *ngIf="(currentObs | async) && !(isLoadingObs | async) && !(isLoadingPersonObs | async)"
                            [model]="currentObs | async"
                            [languages]="languagesObs | async"
                            [licenses]="licensesObs | async"
diff --git a/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.ts b/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.ts
index 2b7adc0de..f02868412 100644
--- a/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.ts
+++ b/src/app/features/deposit/components/routables/deposit-edit/deposit-edit.routable.ts
@@ -2,6 +2,7 @@ import {
   ChangeDetectionStrategy,
   Component,
   OnInit,
+  ViewChild,
 } from "@angular/core";
 import {ActivatedRoute} from "@angular/router";
 import {DepositExtended} from "@app/features/deposit/models/deposits-extended.model";
@@ -21,6 +22,7 @@ import {SharedAbstractEditRoutable} from "@app/shared/components/routables/share
 import {LocalStateEnum} from "@app/shared/enums/local-state.enum";
 import {LocalStateModel} from "@app/shared/models/local-state.model";
 import {SharedOrgUnitAction} from "@app/shared/stores/organizational-unit/shared-organizational-unit.action";
+import {DepositFormPresentational} from "@deposit/components/presentationals/deposit-form/deposit-form.presentational";
 import {
   Select,
   Store,
@@ -44,6 +46,9 @@ export class DepositEditRoutable extends SharedAbstractEditRoutable<DepositExten
   @Select((state: LocalStateModel) => state.shared.shared_organizationalUnit.list) organizationalUnitsObs: Observable<AccessOrganizationalUnit[]>;
   @Select((state: LocalStateModel) => state.deposit.deposit_person.selected) selectedPersonObs: Observable<Person[]>;
 
+  @ViewChild("formPresentational", {static: false})
+  readonly formPresentational: DepositFormPresentational;
+
   constructor(protected store: Store,
               protected route: ActivatedRoute) {
     super(store, route, LocalStateEnum.deposit, depositActionNameSpace);
diff --git a/src/app/features/deposit/models/deposit-data-file.model.ts b/src/app/features/deposit/models/deposit-data-file.model.ts
index af8ea48eb..844be35aa 100644
--- a/src/app/features/deposit/models/deposit-data-file.model.ts
+++ b/src/app/features/deposit/models/deposit-data-file.model.ts
@@ -4,7 +4,18 @@ import {
   ChangeInfo,
   Deposit,
 } from "@app/generated-api";
-import StatusEnum = Deposit.StatusEnum;
+
+export enum DepositDataFileStateEnum {
+  IN_ERROR = "IN_ERROR",
+  READY = "READY",
+  RECEIVED = "RECEIVED",
+  CHANGE_RELATIVE_LOCATION = "CHANGE_RELATIVE_LOCATION",
+  TO_PROCESS = "TO_PROCESS",
+  PROCESSED = "PROCESSED",
+  FILE_FORMAT_IDENTIFIED = "FILE_FORMAT_IDENTIFIED",
+  FILE_FORMAT_UNKNOWN = "FILE_FORMAT_UNKNOWN",
+  VIRUS_CHECKED = "VIRUS_CHECKED"
+}
 
 export interface DepositDataFile {
   resId?: string;
@@ -15,7 +26,7 @@ export interface DepositDataFile {
   relativeLocation?: string;
   finalData?: string;
   fileSize?: number;
-  status?: StatusEnum;
+  status?: DepositDataFileStateEnum;
   statusMessage?: string;
   dataCategory?: string; // Enum get with ApiActionEnum.LIST_DATA_CATEGORY
   dataType?: string; // Enum get with ApiActionEnum.LIST_DATA_TYPE
diff --git a/src/app/shared/components/presentationals/shared-abstract-form/shared-abstract-form.presentational.ts b/src/app/shared/components/presentationals/shared-abstract-form/shared-abstract-form.presentational.ts
index 7bd98a651..4ae9370dc 100644
--- a/src/app/shared/components/presentationals/shared-abstract-form/shared-abstract-form.presentational.ts
+++ b/src/app/shared/components/presentationals/shared-abstract-form/shared-abstract-form.presentational.ts
@@ -32,6 +32,8 @@ export abstract class SharedAbstractFormPresentational<T> extends SharedAbstract
   @Input()
   readonly: boolean;
 
+  isValidWhenDisable: boolean;
+
   private readonly _submitBS: BehaviorSubject<ModelFormControlEvent<T> | undefined> = new BehaviorSubject<ModelFormControlEvent<T> | undefined>(undefined);
 
   @Output("submitChange")
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 bdd5b9009..0bcb68947 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
@@ -1,4 +1,5 @@
 @import "../../../../../sass/abstracts/variables";
+@import "../../../../../sass/abstracts/mixins";
 
 $fontFamily: Helvetica, Arial, sans-serif;
 $fontSize: 1em;
@@ -57,16 +58,19 @@ $invalidInputBorderColor: #ff0084;
 $inputGroupTextColor: #444444;
 
 .data-table {
-
   .no-datas {
     text-align: center;
   }
 
-  tbody tr:nth-child(odd) {
-    // Allow pyjama
-    background-color: $background-grey !important;
+  tbody{
+    tr:nth-child(odd) {
+      // Allow pyjama
+      background-color: $background-grey !important;
+    }
+    td {
+      @include truncate-with-ellipsis();
+    }
   }
-
   @import "./base/table";
 
   // OVERRIDE RULE PRIME NG THEME BELOW
@@ -93,6 +97,7 @@ $inputGroupTextColor: #444444;
     color: $headerTextColor !important;
   }
 
+
   .data-table-filter {
     padding: 4px !important;
 
diff --git a/src/app/shared/pipes/all-data-file-ready.pipe.ts b/src/app/shared/pipes/all-data-file-ready.pipe.ts
new file mode 100644
index 000000000..3dc6599db
--- /dev/null
+++ b/src/app/shared/pipes/all-data-file-ready.pipe.ts
@@ -0,0 +1,29 @@
+import {
+  Pipe,
+  PipeTransform,
+} from "@angular/core";
+import {
+  DepositDataFile,
+  DepositDataFileStateEnum,
+} from "@deposit/models/deposit-data-file.model";
+import {SharedAbstractPipe} from "@shared/pipes/shared-abstract/shared-abstract.pipe";
+
+@Pipe({
+  name: "allDataFileReady",
+})
+export class AllDataFileReadyPipe extends SharedAbstractPipe implements PipeTransform {
+  transform(list: DepositDataFile[]): boolean {
+    if (list === undefined || list === null) {
+      return false;
+    }
+    if (list.length === 0) {
+      return false;
+    }
+    list.forEach(d => {
+      if (d.status === DepositDataFileStateEnum.READY) {
+        return false;
+      }
+    });
+    return true;
+  }
+}
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index 42caa1cce..6c6688810 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -26,6 +26,7 @@ import {library} from "@fortawesome/fontawesome-svg-core";
 import {fas} from "@fortawesome/free-solid-svg-icons";
 import {TranslateModule} from "@ngx-translate/core";
 import {NgxsModule} from "@ngxs/store";
+import {AllDataFileReadyPipe} from "@shared/pipes/all-data-file-ready.pipe";
 import {TableModule} from "primeng/table";
 import {SolidifyFrontendModule} from "solidify-frontend";
 import {SharedBreadcrumbPresentational} from "./components/presentationals/shared-breadcrumb/shared-breadcrumb.presentational";
@@ -45,7 +46,7 @@ const presentationals = [
   SharedErrorPresentational,
 ];
 const directives = [SharedValidationDirective];
-const pipes = [FileSizePipe];
+const pipes = [FileSizePipe, AllDataFileReadyPipe];
 const modules = [
   CommonModule,
   FormsModule,
diff --git a/src/sass/abstracts/_mixins.scss b/src/sass/abstracts/_mixins.scss
index 269f1deae..aef070044 100644
--- a/src/sass/abstracts/_mixins.scss
+++ b/src/sass/abstracts/_mixins.scss
@@ -102,3 +102,9 @@ $breakpoints-media-interval: (
     opacity: 0.5;
   }
 }
+
+@mixin truncate-with-ellipsis(){
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
-- 
GitLab