From 0ec5837d853082ff8af8c8ec4ac0d64e7da1f750 Mon Sep 17 00:00:00 2001
From: mechtelm <nicht@mehr.fragen>
Date: Sun, 7 Apr 2019 12:17:34 +0200
Subject: [PATCH] v1.2: lazy loading

---
 src/app/start/start.component.html            |  4 +-
 src/app/start/start.component.ts              |  6 +-
 .../test-controller.classes.ts                | 24 +++++++
 .../test-controller.component.html            |  2 +-
 .../test-controller.component.ts              | 22 ++++--
 .../test-controller.service.ts                |  2 +
 .../unithost/unit-routing-guards.ts           | 71 ++++++++++++++++---
 src/environments/environment.build.ts         |  2 +-
 src/environments/environment.prod.ts          |  2 +-
 9 files changed, 116 insertions(+), 19 deletions(-)

diff --git a/src/app/start/start.component.html b/src/app/start/start.component.html
index 15babd75..1bd0b30b 100644
--- a/src/app/start/start.component.html
+++ b/src/app/start/start.component.html
@@ -49,7 +49,7 @@
 
     <!-- - - - - - - - - - - - - - - - - -->
     <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showBookletButtons">
-      <mat-card-title>{{ showBookletButtons | customText:'login_bookletSelectTitle' }}</mat-card-title>
+      <mat-card-title>{{ bookletSelectTitle }}</mat-card-title>
       <mat-card-content>
         <div fxLayout="row" fxLayoutGap="10px" fxLayout="column">
           <p *ngIf="bookletlist.length === 0">
@@ -114,7 +114,7 @@
 
         <!-- - - - - - - - - - - - - - - - - -->
         <div *ngIf="showBookletButtons">
-          <p>{{ showBookletButtons | customText:'login_bookletSelectPrompt' }}</p>
+          <p>{{ bookletSelectPrompt }}</p>
         </div>
 
         <!-- - - - - - - - - - - - - - - - - -->
diff --git a/src/app/start/start.component.ts b/src/app/start/start.component.ts
index 68013de5..bfe9a6b2 100644
--- a/src/app/start/start.component.ts
+++ b/src/app/start/start.component.ts
@@ -26,12 +26,12 @@ export class StartComponent implements OnInit, OnDestroy {
   // for template
   private validCodes = [];
   private loginStatusText = ['nicht angemeldet'];
+  public bookletSelectTitle = 'Bitte wählen';
 
   private testtakerloginform: FormGroup;
   private codeinputform: FormGroup;
   private lastloginname = '';
-  private bookletSelectPrompt = 'Bitte wählen';
-  private bookletSelectTitle = 'Bitte wählen';
+  public bookletSelectPrompt = 'Bitte wählen';
 
   // ??
   // private sessiondata: PersonBooklets;
@@ -143,8 +143,10 @@ export class StartComponent implements OnInit, OnDestroy {
                 this.bookletSelectPrompt = (allOk.length > 1) ? 'Testhefte beendet' : 'Testheft beendet';
                 this.bookletSelectTitle = 'Beendet';
               } else if (numberOfOpenBooklets === 1) {
+                this.bookletSelectPrompt = 'Bitte links auf den Testheft-Schalter klicken!';
                 this.bookletSelectTitle = 'Bitte starten';
               } else {
+                this.bookletSelectPrompt = 'Bitte links ein Testheft wählen und klicken!';
                 this.bookletSelectTitle = 'Bitte wählen';
               }
             });
diff --git a/src/app/test-controller/test-controller.classes.ts b/src/app/test-controller/test-controller.classes.ts
index 18096d11..d031b82c 100644
--- a/src/app/test-controller/test-controller.classes.ts
+++ b/src/app/test-controller/test-controller.classes.ts
@@ -233,6 +233,30 @@ export class Testlet extends TestletContentElement {
     return myreturn;
   }
 
+  // .....................................................................
+  getAllUnitSequenceIds(testletId = ''): number[] {
+    let myreturn = [];
+
+    if (testletId) {
+      // find testlet
+      const myTestlet = this.getTestlet(testletId);
+      if (myTestlet) {
+        myreturn = myTestlet.getAllUnitSequenceIds();
+      }
+    } else {
+      for (const tce of this.children) {
+        if (tce instanceof Testlet) {
+          const localTestlet = tce as Testlet;
+          localTestlet.getAllUnitSequenceIds().forEach(u => myreturn.push(u));
+        } else {
+          const localUnit = tce as UnitDef;
+          myreturn.push(localUnit.sequenceId);
+        }
+      }
+    }
+    return myreturn;
+  }
+
   // .....................................................................
   setTimeLeftNull(testletId = '') {
     if (testletId) {
diff --git a/src/app/test-controller/test-controller.component.html b/src/app/test-controller/test-controller.component.html
index c950aa4b..4c826329 100644
--- a/src/app/test-controller/test-controller.component.html
+++ b/src/app/test-controller/test-controller.component.html
@@ -35,7 +35,7 @@
 </div>
 <mat-card *ngIf="showProgress" class="progress-bar">
   <mat-card-content fxLaxout="column">
-    <h2>Lade alle Aufgaben... bitte warten</h2>
+    <h2>Lade Aufgaben... bitte warten</h2>
     <mat-progress-bar
         color="primary"
         mode="determinate"
diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts
index 420fab99..8ed55d35 100644
--- a/src/app/test-controller/test-controller.component.ts
+++ b/src/app/test-controller/test-controller.component.ts
@@ -527,18 +527,20 @@ export class TestControllerComponent implements OnInit, OnDestroy {
                     },
                     err => console.error('unit load error from loadUnitOk: ' + err),
                     () => {
-                      this.showProgress = false;
-                      this.tcs.dataLoading = false;
 
                       // =====================
                       this.tcs.bookletDbId = loginData.booklet;
                       this.tcs.rootTestlet.lockUnitsIfTimeLeftNull();
                       this.tcs.updateMinMaxUnitSequenceId(navTarget);
+                      this.loadedUnitCount = 0;
 
                       // =====================
                       this.unitLoadQueueSubscription2 = from(this.unitLoadQueue).pipe(
                         concatMap(queueEntry => {
                           const unitSequ = Number(queueEntry.tag);
+                          if (!this.tcs.lazyloading) {
+                            this.incrementProgressValueBy1();
+                          }
                           // avoid to load unit def if not necessary
                           if (unitSequ < this.tcs.minUnitSequenceId) {
                             return of({tag: unitSequ.toString(), value: ''});
@@ -556,10 +558,22 @@ export class TestControllerComponent implements OnInit, OnDestroy {
                           }
                         },
                         err => console.error('unit load error: ' + err),
-                        () => this.tcs.addBookletLog(LogEntryKey.BOOKLETLOADCOMPLETE) // complete
+                        () => { // complete
+                          this.tcs.addBookletLog(LogEntryKey.BOOKLETLOADCOMPLETE);
+                          this.tcs.bookletLoadComplete = true;
+                          if (!this.tcs.lazyloading) {
+                              this.showProgress = false;
+                              this.tcs.dataLoading = false;
+                              this.tcs.setUnitNavigationRequest(navTarget.toString());
+                          }
+                        }
                       );
 
-                      this.tcs.setUnitNavigationRequest(navTarget.toString());
+                      if (this.tcs.lazyloading) {
+                        this.showProgress = false;
+                        this.tcs.dataLoading = false;
+                        this.tcs.setUnitNavigationRequest(navTarget.toString());
+                      }
 
                     } // complete
                 );
diff --git a/src/app/test-controller/test-controller.service.ts b/src/app/test-controller/test-controller.service.ts
index 34ade045..5d26da66 100644
--- a/src/app/test-controller/test-controller.service.ts
+++ b/src/app/test-controller/test-controller.service.ts
@@ -25,6 +25,7 @@ export class TestControllerService {
   public logging = true;
   public lazyloading = true;
   public dataLoading = false;
+  public bookletLoadComplete = false;
 
   public navigationRequest$ = new Subject<string>();
   public maxTimeTimer$ = new Subject<MaxTimerData>();
@@ -137,6 +138,7 @@ export class TestControllerService {
     this.lazyloading = true;
     this._costumTexts = {};
     this.dataLoading = false;
+    this.bookletLoadComplete = false;
   }
 
   // 7777777777777777777777777777777777777777777777777777777777777777777777
diff --git a/src/app/test-controller/unithost/unit-routing-guards.ts b/src/app/test-controller/unithost/unit-routing-guards.ts
index bcf4ad1c..3cf82309 100644
--- a/src/app/test-controller/unithost/unit-routing-guards.ts
+++ b/src/app/test-controller/unithost/unit-routing-guards.ts
@@ -170,16 +170,71 @@ export class UnitActivateGuard implements CanActivate {
 
   // ****************************************************************************************
   checkAndSolve_DefLoaded(newUnit: UnitControllerData): Observable<Boolean> {
-    if (this.tcs.hasUnitDefinition(newUnit.unitDef.sequenceId)) {
+    if (this.tcs.bookletLoadComplete) {
       return of(true);
     } else {
-      this.tcs.dataLoading = true;
-      return interval(1000)
-        .pipe(
-          filter(intervalvalue => this.tcs.hasUnitDefinition(newUnit.unitDef.sequenceId)),
-          map(v => true),
-          take(1)
-        );
+      if (this.tcs.currentUnitSequenceId < newUnit.unitDef.sequenceId) {
+
+        // 1 going forwards
+
+        if ((newUnit.maxTimerRequiringTestlet === null) || (this.tcs.mode === 'review')) {
+
+          // 1 a) target is not in timed block or review mode --> check only target unit
+
+          if (this.tcs.hasUnitDefinition(newUnit.unitDef.sequenceId)) {
+            return of(true);
+          } else {
+            this.tcs.dataLoading = true;
+            return interval(1000)
+              .pipe(
+                filter(intervalvalue => this.tcs.hasUnitDefinition(newUnit.unitDef.sequenceId)),
+                map(v => true),
+                take(1)
+              );
+          }
+        } else if (this.tcs.currentMaxTimerTestletId && (newUnit.maxTimerRequiringTestlet.id === this.tcs.currentMaxTimerTestletId)) {
+
+          // 1 b) staying in timed block --> check has been already done
+
+          return of(true);
+
+        } else {
+
+          // entering timed block --> check all units
+          const allUnitsSequenceIdsToCheck = this.tcs.rootTestlet.getAllUnitSequenceIds(newUnit.maxTimerRequiringTestlet.id);
+          let ok = true;
+          allUnitsSequenceIdsToCheck.forEach(u => {
+            if (!this.tcs.hasUnitDefinition(u)) {
+              ok = false;
+            }
+          });
+          if (ok) {
+            return of(true);
+          } else {
+            this.tcs.dataLoading = true;
+            return interval(1000)
+              .pipe(
+                filter(intervalvalue => {
+                  let localOk = true;
+                  allUnitsSequenceIdsToCheck.forEach(u => {
+                    if (!this.tcs.hasUnitDefinition(u)) {
+                      localOk = false;
+                    }
+                  });
+                  return localOk;
+                }),
+                map(v => true),
+                take(1)
+              );
+          }
+
+        }
+      } else {
+
+        // 2 going backwards --> no check, because units are loaded in ascending order
+
+        return of(true);
+      }
     }
   }
 
diff --git a/src/environments/environment.build.ts b/src/environments/environment.build.ts
index d5aa2171..f6143522 100644
--- a/src/environments/environment.build.ts
+++ b/src/environments/environment.build.ts
@@ -5,5 +5,5 @@ export const environment = {
   testcenterUrl: '/',
   appName: 'IQB-Testcenter',
   appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen',
-  appVersion: '1.1.5 - 31.3.2019'
+  appVersion: '1.2 - 7.4.2019'
 };
diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts
index b4ab55f7..c17f9a3b 100644
--- a/src/environments/environment.prod.ts
+++ b/src/environments/environment.prod.ts
@@ -5,5 +5,5 @@ export const environment = {
   testcenterUrl: '/',
   appName: 'IQB-Testcenter',
   appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen',
-  appVersion: '1.1.5 - 31.3.2019'
+  appVersion: '1.2 - 7.4.2019'
 };
-- 
GitLab